【问题标题】:Is there a better way to get this data?有没有更好的方法来获取这些数据?
【发布时间】:2012-05-23 10:49:03
【问题描述】:

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

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

【问题讨论】:

  • 对我来说看起来还不错。不过这个问题可能更适合codereview.stackexchange.com

标签: javascript jquery arrays underscore.js


【解决方案1】:

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

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

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

您也可以通过在map 中使用find 来跳过pluckflatten

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2019-05-14
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      • 2011-03-09
      • 2019-08-26
      • 1970-01-01
      相关资源
      最近更新 更多