Sort array containing objects based on another array using _Underscore

只谈情不闲聊 提交于 2019-12-08 21:49:32

问题


I already read the previous questions answered, but it didn't fit with my need.

I have an array of objects such as

var Widgets = [
             [{Id: 'abcdef', post_id: 12345}],
             [{Id: 'ghijkl', post_id: 45678}],
             [{Id: 'mnoptq', post_id: 90123}]
];

I have a second array :

var sortArray = ['ghijkl', 'mnoptq', 'abcdef'];

I need To reorder Widgets with the initial order of elements which appears on sortArray

i've succeed to do it this way

sortArray.forEach(function(Id) {
                    var found = false;                  
                    Widgets = Widgets.filter(function(Widget) {
                        if(!found && Widget.Id == Id) {
                            NewWidgets.push(Widget);
                            found = true;
                            return false;
                        } else {
                            return true;
                        }
                    });
                });

But I wish to improve this code by using _SortBy but I didn't succeed so far...

Anyhelp ?

Edit

Final result should be

var Widgets = [
             [{Id: 'ghijkl', post_id: 45678}],
             [{Id: 'mnoptq', post_id: 90123}],
             [{Id: 'abcdef', post_id: 12345}]
];

回答1:


Like this?

sorted = _.sortBy(Widgets, function(x) {
    return _.indexOf(sortArray, x[0].Id)
})

This is not very efficient, a faster way is to convert sortArray to an object key=>index and use hash lookups in sortBy:

sortObj = _.invert(_.object(_.pairs(sortArray)));

sorted = _.sortBy(Widgets, function(x) {
    return sortObj[x[0].Id]
})



回答2:


On top of @georg's solution, if performance is really important to you, and you have to keep something like this1, then preparing the key/index object using the following will be much faster:

// Example: ['a', 'b', 'c'] becomes { 'a': 0, 'b': 1, 'c': 2 }
var sortObj = sortArray.reduce(function(acc, value, index) {
  acc[value] = index;
  return acc;
}, {});

// Same as posted by @georg, with no need for `parseInt`
sorted = _.sortBy(Widgets, function(Widget) {
  return sortObj[Widget[0].Id];
});

It's a bit longer but also I'd argue it's also easier to read than the invert/object/pairs.

Also, note that there is no need for parseInt with this solution, because it builds an object of integer values, while the other solution returns strings.

1 Because let's face it, there are other ways to improve this if you actually can give it a bigger refactor.



来源:https://stackoverflow.com/questions/28673656/sort-array-containing-objects-based-on-another-array-using-underscore

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