ABC*_*ABC 3 javascript ramda.js
我有2个数组
a = [2,3,1,4]
b = [{id: 1}, {id: 2}, {id: 3}, {id: 4}]
Run Code Online (Sandbox Code Playgroud)
如何b根据排序a?我想要的输出是
c = [{id: 2}, {id: 3}, {id: 1}, {id: 4}]
Run Code Online (Sandbox Code Playgroud)
我更喜欢使用Ramda或常规JS。
Ramda对于这些类型的问题确实很满意。
在数据大小较小的地方,我们可以使用简单的reduce函数和indexOf帮助器。
// match id of object to required index and insert
var sortInsert = function (acc, cur) {
var toIdx = R.indexOf(cur.id, a);
acc[toIdx] = cur;
return acc;
};
// point-free sort function created
var sort = R.reduce(sortInsert, []);
// execute it now, or later as required
sort(b);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]
Run Code Online (Sandbox Code Playgroud)
这对于小型(ish)数据集效果很好,但是对于大型数据集,通过归约的每次迭代的indexOf操作效率都较低。
我们可以通过从另一侧解决问题来解决此问题,让我们使用groupBy将对象按其ID分组,从而创建字典查找(更好!)。然后,我们可以简单地映射所需的索引,并将其转换为该位置处的相应对象。
这是使用这种方法的解决方案:
var groupById = R.groupBy(R.prop('id'), b);
var sort = R.map(function (id) {
return groupById[id][0];
});
sort(a);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]
Run Code Online (Sandbox Code Playgroud)
最后,这是另一种非常简洁的解决方案:
R.sortBy(R.pipe(R.prop('id'), R.indexOf(R.__, a)))(b);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]
Run Code Online (Sandbox Code Playgroud)
我喜欢这样的方式:您可以使用行为组合功能,并使用Ramda将算法与算法所依据的数据分开。您最终将获得易于阅读且易于维护的代码。
使用 ES6 映射和查找
const a = [2,3,1,4];
const b = [{id: 1}, {id: 2}, {id: 3}, {id: 4}];
// map over a, find it in b and return
const c = a.map((i) => b.find((j) => j.id === i));
Run Code Online (Sandbox Code Playgroud)
您可以为JavaScript的Array#sort方法提供自定义比较功能。
使用自定义比较功能来确保排序顺序:
var sortOrder = [2,3,1,4],
items = [{id: 1}, {id: 2}, {id: 3}, {id: 4}];
items.sort(function(a, b){
return sortOrder.indexOf(a.id) - sortOrder.indexOf(b.id);
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2844 次 |
| 最近记录: |