使用Underscore对包含基于另一个数组的对象的数组进行排序

时间:2015-02-23 12:18:12

标签: javascript arrays underscore.js

我已经阅读了之前回答的问题,但这并不符合我的需要。

我有一组对象,例如

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

我有第二个数组:

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

我需要使用sortArray

上显示的元素的初始顺序重新排序窗口小部件

我已经成功地这样做了

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

但我希望通过使用_SortBy改进此代码,但到目前为止我还没有成功......

Anyhelp?

修改

最终结果应为

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

2 个答案:

答案 0 :(得分:5)

喜欢这个吗?

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

这不是非常有效,更快的方法是将sortArray转换为对象key=>index并在sortBy中使用哈希查找:

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

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

答案 1 :(得分:0)

在@ georg的解决方案之上,如果性能对您非常重要,并且您必须保留类似 1 的内容,那么使用以下内容准备密钥/索引对象要快得多:

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

它有点长,但我也认为它比invert / object / pairs更容易阅读。

另请注意,parseInt不需要此解决方案,因为它构建了一个整数值对象,而另一个解决方案返回字符串。

1 因为让我们面对它,如果你真的可以给它一个更大的重构,还有其他方法来改善它。