根据另一个ID数组对对象数组进行排序 [英] Sort an array of objects based on another array of ids

查看:335
本文介绍了根据另一个ID数组对对象数组进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个数组

a = [2,3,1,4]
b = [{id: 1}, {id: 2}, {id: 3}, {id: 4}]

如何获取基于a排序的b?我想要的输出是

c = [{id: 2}, {id: 3}, {id: 1}, {id: 4}]

我更喜欢使用Ramda或常规JS.

解决方案

Ramda 确实针对这些类型的问题大放异彩.

在数据量较小的地方,我们可以使用简单的减少函数和 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 } ]

这对于较小的数据集效果很好,但是在每次迭代过程中,每次操作 indexOf 操作缩减对于大型数据集而言效率不高.

我们可以通过从另一侧解决问题来补救此问题,让我们使用 groupBy 对我们的分组对象的ID,从而创建字典查找(更好!).然后,我们可以在所需索引上简单地 map 并将其转换为该位置的相应对象.

这是使用这种方法的解决方案:

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 } ]

最后,这是另一个简洁的解决方案:

R.sortBy(R.pipe(R.prop('id'), R.indexOf(R.__, a)))(b);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]

我喜欢这样的方法:您可以使用行为将函数组合为行为,并使用 解决方案

Ramda really shines for these types of problems.

Where the size of the data is small, we can use a simple reduce function, and indexOf helper.

// 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 } ]

This works well for small(ish) data sets but the indexOf operation on every iteration through the reduction is inefficient for large data sets.

We can remedy this by tackling the problem from the other side, lets use groupBy to group our objects by their id, thus creating a dictionary lookup (much better!). We can then simply map over the required indexes and transform them to their corresponding object at that position.

And here is the solution using this approach:

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 } ]

Finally, this is yet another solution, which is very succinct:

R.sortBy(R.pipe(R.prop('id'), R.indexOf(R.__, a)))(b);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]

I love the way you can compose functions with behaviour and separate the algorithm from the data upon which it acts using Ramda. You end up with very readable, and easy to maintain code.

这篇关于根据另一个ID数组对对象数组进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆