underscore.js根据另一个对象过滤一个对象数组

时间:2013-02-27 03:10:26

标签: javascript underscore.js

我正在尝试根据另一个过滤对象数组。公共属性标识id。 我不确定过滤器+每个是最好的方法或映射减少。无论如何,下面的代码不起作用,因为out是空列表。

var aaa = [
    {name: "AAA", id: 845},
    {name: "BBB", id: 839},
    {name: "CCC", id: 854}
];
var bbb = [
    {id: 839},
    {id: 854}
];

var out = _.filter(aaa, function(val){
    return _.each(this, function(val2){
        return val['id'] === val2['id']
    });
}, bbb);

4 个答案:

答案 0 :(得分:37)

只需创建有效ID的“set”并使用“set”进行过滤:

var aaa = [
    {name: "AAA", id: 845},
    {name: "BBB", id: 839},
    {name: "CCC", id: 854}
];
var bbb = [
    {id: 839},
    {id: 854}
];

var ids = {};
_.each(bbb, function (bb) { ids[bb.id] = true; });

var out = _.filter(aaa, function (val) {
    return ids[val.id];
}, bbb);

填充ids很快,它在n * amortized O(1)中,即O(n)。同样适用于过滤。

如果在内循环中使用each(…),则会有O(n²)。对于更大的数据集,这将变得非常慢。此外,额外的嵌套使代码更难以阅读/理解乍一看。

查看已截断的代码:http://jsfiddle.net/SMtX5/

答案 1 :(得分:17)

您可以使用_.find过滤:

_.filter(aaa, function(a){
    return _.find(bbb, function(b){
        return b.id === a.id;
    });
});

答案 2 :(得分:2)

您可以使用_.some(list, [iterator], [context])

如果列表中的任何值通过迭代器真值测试,则返回 true

var out = _.filter(aaa, function(val){
    return _.some(this,function(val2){
        return val2['id'] === val['id'];
    });
}, bbb);

这是jsfiddle。 http://jsfiddle.net/h98ej/

答案 3 :(得分:2)

bbb = bbb.map(_ => _.id) && aaa.filter(_ => bbb.indexOf( _.id ) > -1)

假设您的用例,您只需要纯JS数组函数即可。