Underscore.js:使用嵌套属性值查找findWhere

26

如何进行以下过滤:

[{
    "id": 100,
    "title": "Tlt1",
    "tax": [{
        "name": "Tax1",
        "id": 15
    }, {
        "name": "Tax1",
        "id": 17
    }]
}, {
    "id": 101,
    "title": "Tlt2",
    "tax": [{
        "name": "Tax2",
        "id": 16
    }]
}, {
    "id": 102,
    "title": "Tlt3",
    "tax": [{
        "name": "Tax3",
        "id": 17
    }, {
        "name": "Tax3",
        "id": 18
    }]
}]

根据以下命令,只获取 tax.id17 的信息:

[
    {
        "id": 100,
        "title": "Tlt1",
        "tax": [
            {
                "name": "Tax1",
                "id": 15
            },
            {
                "name": "Tax1",
                "id": 17
            }
        ]
    },
    {
        "id": 102,
        "title": "Tlt3",
        "tax": [
            {
                "name": "Tax3",
                "id": 17
            },
            {
                "name": "Tax3",
                "id": 18
            }
        ]
    }
]

目前我使用以下方法,但可能有更加简洁的方式吗?

var arr = [];
_(data).each(function (v1, k1) {
    _(v1.tax).each(function (v2, k2) {
        if (v2.id == id) {
            arr.push(v1);
        }
    });
});

演示在这里:http://jsfiddle.net/7gcCz/2/ 非常感谢任何建议。

这可能是CR的候选项... - user57508
3个回答

51

你可以使用 _.filter_.where 的组合方法。

_.filter(data, function(obj) {
    return _.where(obj.tax, {id: ID_TO_FIND}).length > 0;
})

查看演示:http://jsfiddle.net/hCVxp/

更新


感谢@GruffBunny。更有效的方法是使用_.some来避免循环遍历所有tax项:

var arr = _.filter(data, function(obj) {
    return _.some(obj.tax, {id: ID_TO_FIND});
});

查看演示:http://jsbin.com/putefarade/1/edit?html,js,console


5
第一次使用 underscore,第一个障碍,谷歌上的第一个链接,赢了! - MattSizzle
1
如果税只是一个对象,你必须将它放在一个数组中才能使它起作用。就像这样:_.some([obj.tax], {id: ID_TO_FIND}); - Jmirancid Pes

20
使用 _.filter 查找候选项,并使用 _.some 检查集合中是否存在该项:
var filteredList = _.filter(list, function(item){
    return _.some(item.tax, { id: 17 });
});

我认为这个答案比上面被接受的答案更高效。 - Justin McCandless
我可以在 filter 中使用 _.findWhere 吗? - Jain

3
你可以仅使用 _.where 方法来实现这个。
var filteredList  = _.where(list, { tax:[{id:17}] });

更新:这种方法适用于旧版本的lodash,但在当前版本的underscore或lodash中不起作用。 即使如此,以下是一个工作示例: https://jsfiddle.net/rhp4crma/


有人能告诉我为什么这个被踩了吗?我测试过了,只用一个命令就返回了 OP 要求的确切结果。 - Gray
我尝试了这个,但它不起作用。我的返回值是未定义的,尽管该项存在。 - tno2007
1
正确的语法是:var filteredList = _.where(list, { tax:{id:17} }); - Sam
我已经点赞了你的回答,以鼓励你参与SO,请更新你的回答,加上针对这个特定情况的jsfiddle示例链接,并按照@Sam的建议更新你的回答纠正者。 - Mahdi Alkhatib

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接