有没有更好的方法来获取这些数据?

时间:2012-05-23 10:49:04

标签: javascript jquery arrays underscore.js

我使用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);

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

2 个答案:

答案 0 :(得分:2)

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

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

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

您还可以在pluck内使用flatten跳过findmap

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中的数组。您还必须跟踪this.items中对idx的任何更改,但如果您将其全部隐藏在对象内并且只通过该对象的方法来处理数据,那么这很容易。

答案 1 :(得分:0)

聪明的方法,但随着对象大小的增长(对子阵列的多次操作)效率最高。我认为最好做两个underscore.js发现:首先匹配 menuitem 匹配titlex,然后匹配数据匹配titlex-y。

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