Lodash sort collection based on external array

安稳与你 提交于 2019-12-19 05:07:08

问题


I have an array with keys like so:

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

and a collection which has these keys in each object like so:

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

Is there a fast way to sort the collection based on the order of keys in the first array?


回答1:


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



回答2:


Input:

var data1 = ['129asg', '39342aa'];
var data2 = [{
    guid: '39342aa',
    name: 'John'
}, {
    guid: '129asg',
    name: 'Mary'
}];
  1. First create an index object, with _.reduce, like this

    var indexObject = _.reduce(data2, function(result, currentObject) {
        result[currentObject.guid] = currentObject;
        return result;
    }, {});
    
  2. And then map the items of the first array with the objects from the indexObject, like this

    console.log(_.map(data1, function(currentGUID) {
        return indexObject[currentGUID]
    }));
    

Output

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

Note: This method will be very efficient if you want to sort so many objects, because it will reduce the linear look-up in the second array which would make the entire logic run in O(M * N) time complexity.




回答3:


You can use indexBy(), and at() to sort your collection. The advantage being that concise code and performance. Using sortBy() here does the trick, but your external array is already sorted:

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

Using at(), you can iterate over the sorted external collection, building a new collection from the source collection. The source collection has been transformed into an object using indexBy(). You do this so at() has key-based access for each of it's ids.




回答4:


Here is just a simple add to the accepted answer in case you want to put the unmatched elements at the end of the sortedCollection and not at the beginning:

const last = collection.length;

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


来源:https://stackoverflow.com/questions/28719795/lodash-sort-collection-based-on-external-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!