2

我使用 jQuery 和underscore.js,我有title1-2并且我希望有相应的动作。

this.items = {
    menuItems: [
        { title: 'title1',
            data: [
                { title: 'title1-1',
                    action: 'action1-1'
                },
                { title: 'title1-2',
                    action: 'action1-2'
                }
                ]
        },
        { title: 'title2',
            data: [
                { title: 'title2-1',
                    action: 'action2-1'
                },
                { title: 'title2-2',
                    action: 'action2-2'
                }
            ]
        }
    ]
};

目前,我有以下代码来执行此操作:

var item = _.find(_.flatten(_.pluck(this.items.menuItems, 'data')), function (item) { return item.title === 'title1-2'; });
console.log(item.action);

有没有更好的方法找到它?

4

2 回答 2

2

切换到_.chain会使它更容易理解:

var item = _.chain(items.menuItems)
            .pluck('data')
            .flatten()
            .find(function(i) { return i.title === 'title1-2' })
            .value();

演示:http: //jsfiddle.net/ambiguous/mPa3m/

您也可以通过在 a中使用 a 来跳过pluckand :flattenfindmap

var right_title = function(i) { return i.title === 'title1-2' };
var is_there    = function(i) { return i };
var item        = _.chain(items.menuItems)
                   .map(function(i) { return _(i.data).find(right_title) })
                   .find(is_there)
                   .value();

演示:http: //jsfiddle.net/ambiguous/uRBuZ/

或者只是去老派并使用短路嵌套循环:

var i, j, sub, item;
for(i = 0, item = null; !item && i < items.menuItems.length; ++i)
    for(j = 0, sub = items.menuItems[i]; !item && j < sub.data.length; ++j)
        if(sub.data[j].title === 'title2-1')
            item = sub.data[j];

演示:http: //jsfiddle.net/ambiguous/7xt5D/

这个只复制了几个引用,所以它应该很容易记忆,它会在第一个可能的机会停止,所以它也很懒惰。

如果您经常这样做,那么建立一个索引以便您可以通过标题直接访问可能是有意义的:

var idx = { };
var i, j, sub, item;
for(i = 0, item = null; !item && i < items.menuItems.length; ++i)
    for(j = 0, sub = items.menuItems[i]; !item && j < sub.data.length; ++j)
        idx[sub.data[j].title] = sub.data[j];
console.log(idx['title1-2']);

演示:http: //jsfiddle.net/ambiguous/SJuHp/

以上假设您的标题是唯一的,但idx如果这是一个问题,您可以轻松地切换到数组。您还必须跟踪对 in 的任何更改this.itemsidx但如果您将其全部隐藏在一个对象中并且只通过该对象的方法来处理数据,这很容易。

于 2012-05-23T15:50:09.130 回答
0

巧妙的方法,但随着对象大小的增长(对子数组的多次操作)不是最有效的。我认为最好做两个 underscore.js 查找:首先是匹配 titlex 的菜单项,然后是匹配 titlex-y的数据。

var item = _.find(
    _.find(
        this.items.menuItems, function(item) {
            return item.title === 'title1'
        }).data,
    function(item) {
        return item.title = 'title1-2'
    });
于 2012-05-23T15:32:26.187 回答