基于外部数组的Lodash排序集合

时间:2015-02-25 13:06:02

标签: javascript arrays collections underscore.js lodash

我有一个像这样的键的数组:

['asdf12','39342aa','12399','129asg',...] 

和一个在每个对象中都有这些键的集合,如下所示:

[{guid: '39342aa', name: 'John'},{guid: '129asg', name: 'Mary'}, ... ]

是否有一种快速的方法可以根据第一个数组中键的顺序对集合进行排序?

5 个答案:

答案 0 :(得分:37)

var sortedCollection = _.sortBy(collection, function(item){
  return firstArray.indexOf(item.guid)
});

答案 1 :(得分:5)

<强>输入:

var data1 = ['129asg', '39342aa'];
var data2 = [{
    guid: '39342aa',
    name: 'John'
}, {
    guid: '129asg',
    name: 'Mary'
}];
  1. 首先使用_.reduce创建一个索引对象,如下所示

    var indexObject = _.reduce(data2, function(result, currentObject) {
        result[currentObject.guid] = currentObject;
        return result;
    }, {});
    
  2. 然后map第一个数组的项目包含来自indexObject的对象,就像这样

    console.log(_.map(data1, function(currentGUID) {
        return indexObject[currentGUID]
    }));
    
  3. <强>输出

    [ { guid: '129asg', name: 'Mary' },
      { guid: '39342aa', name: 'John' } ]
    

    注意:如果要对这么多对象进行排序,这种方法会非常有效,因为它会减少第二个数组中的线性查找,从而使整个逻辑在O中运行( M * N)时间复杂度。

答案 2 :(得分:2)

您可以使用indexBy()at()对收藏品进行排序。优点是简洁的代码和性能。使用sortBy()可以解决这个问题,但外部数组已经排序了:

var ids = [ 'cbdbac14', 'cf3526e2', '189af064' ];

var collection = [
    { guid: '189af064', name: 'John' },
    { guid: 'cf3526e2', name: 'Julie' },
    { guid: 'cbdbac14', name: 'James' }
];

_(collection)
    .indexBy('guid')
    .at(ids)
    .pluck('name')
    .value();
// → [ 'James', 'Julie', 'John' ]

使用at(),您可以遍历已排序的外部集合,从源collection构建新集合。使用indexBy()将源集合转换为对象。这样做是为了使()对每个ids都有基于密钥的访问权限。

答案 3 :(得分:1)

如果您想将不匹配的元素放在sortedCollection的末尾而不是开头,这只是对已接受答案的简单添加:

const last = collection.length;

var sortedCollection = _.sortBy(collection, function(item) {
  return firstArray.indexOf(item.guid) !== -1? firstArray.indexOf(item.guid) : last;
});

答案 4 :(得分:-1)

这是一种高效而干净的方法:

(导入lodash identitysortBy):

TS

function sortByArray<T, U>({ source, by, sourceTransformer = identity }: { source: T[]; by: U[]; sourceTransformer?: (item: T) => U }) {
  const indexesByElements = new Map(by.map((item, idx) => [item, idx]));
  const orderedResult = sortBy(source, (p) => indexesByElements.get(sourceTransformer(p)));
  return orderedResult;
}

或在 JS 中:

function sortByArray({ source, by, sourceTransformer = _.identity }) {
    const indexesByElements = new Map(by.map((item, idx) => [item, idx]));
    const orderedResult = _.sortBy(source, (p) => indexesByElements.get(sourceTransformer(p)));
    return orderedResult;
}