2012-05-23 56 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

相關問題