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

Javascript 基于外部数组的Lodash排序集合,javascript,arrays,collections,underscore.js,lodash,Javascript,Arrays,Collections,Underscore.js,Lodash,我有一个包含如下键的数组: ['asdf12','39342aa','12399','129asg',...] 以及在每个对象中都有这些键的集合,如下所示: [{guid: '39342aa', name: 'John'},{guid: '129asg', name: 'Mary'}, ... ] 是否有一种根据第一个数组中键的顺序对集合进行排序的快速方法?输入: var data1 = ['129asg', '39342aa']; var data2 = [{ guid: '39

我有一个包含如下键的数组:

['asdf12','39342aa','12399','129asg',...] 
以及在每个对象中都有这些键的集合,如下所示:

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

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

输入:

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

    var indexObject = _.reduce(data2, function(result, currentObject) {
        result[currentObject.guid] = currentObject;
        return result;
    }, {});
    
    console.log(_.map(data1, function(currentGUID) {
        return indexObject[currentGUID]
    }));
    
  • 然后
    map
    第一个数组中的项与
    indexObject
    中的对象进行映射,如下所示

    var indexObject = _.reduce(data2, function(result, currentObject) {
        result[currentObject.guid] = currentObject;
        return result;
    }, {});
    
    console.log(_.map(data1, function(currentGUID) {
        return indexObject[currentGUID]
    }));
    
  • 输出

    [ { guid: '129asg', name: 'Mary' },
      { guid: '39342aa', name: 'John' } ]
    
    注意:如果要对这么多对象进行排序,此方法将非常有效,因为它将减少第二个数组中的线性查找,这将使整个逻辑以O(M*N)时间复杂度运行。

    您可以使用此方法对集合进行排序。优点是代码简洁,性能好。在这里使用
    sortBy()
    可以实现这个技巧,但是您的外部数组已经排序了:

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

    使用
    at()
    ,可以迭代已排序的外部集合,从源
    集合构建新集合。已使用
    indexBy()
    将源集合转换为对象。为此,at()对其每个
    id

    都具有基于密钥的访问权限。如果要将不匹配的元素放在sortedCollection的末尾,而不是开头,这里只是对接受答案的一个简单添加:

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

    这是一种高效、干净的方式:

    (导入lodash
    identity
    sortBy
    ):

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

    你用的是什么语言?我在用javascript@silintzir请考虑哪一个对你帮助最大。@ SILIZZIR你问了<代码>一个快速的方式来分类问题中的集合< /代码>。但这不是一个快速的方法,如果你真的是指运行时的性能。这是完美的工作,是最优雅的解决方案,我发现简单的解决方案!它是否保留集合中与第一个数组中的任何元素都不匹配的元素或将其删除?基于多个键进行排序的最有效方法是什么?此答案应随着lodash方式和功能的更改而更新。