2012-05-23 54 views
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); 

有没有更好的办法找到了吗?

+1

对我来说这看起来相当不错。但是,这个问题可能更适合codereview.stackexchange.com –

+0

你最近的问题是什么? – Sangeeta

回答

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' 
    }); 
2

切换到_.chain将使它更容易一点理解:

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

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

你也跳过pluckflatten使用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的阵列。您还必须跟踪idx中的this.items的任何更改,但如果将其全部隐藏在对象中并仅通过该对象的方法处理数据,那么这很容易。

+0

我希望我可以为每个解决方案upvote 1 :-) – Bergi

相关问题