23

我正在尝试根据另一个对象过滤一组对象。公共属性 id id。我不确定 filter + each 是最好的方法还是 map reduce。无论如何,下面的代码不能像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

4 回答 4

40

只需创建一个有效 id 的“集合”并使用该“集合”进行过滤:

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 *摊销O(1) 中,即 O(n)。同样适用于过滤。

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

看到代码在行动中被剪断:http: //jsfiddle.net/SMtX5/

于 2013-02-27T03:23:35.970 回答
20

你可以_.find用来过滤:

_.filter(aaa, function(a){
    return _.find(bbb, function(b){
        return b.id === a.id;
    });
});
于 2013-02-27T03:36:57.903 回答
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/

于 2013-02-27T03:34:33.093 回答
2
bbb = bbb.map(_ => _.id) && aaa.filter(_ => bbb.indexOf( _.id ) > -1)

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

于 2017-06-01T14:29:59.860 回答