2014-06-24 83 views
0

過濾列表中包含列表的對象的最有效方法是什麼?我一直在看下劃線的_.filter函數,但這需要使用數組並返回數組。使用列表篩選對象列表 - Javascript

我想採取一個對象,並通過某個詞過濾它。

例如,我將如何過濾:

[ 
{level: "Title 1", details: [ 
    {real: "There we go", fake: "THERE_WE_GO"}, 
    {real: "Where is it", fake: "WHERE_IS_IT"}, 
    {real: "The dog jumped", fake: "THE_DOG_JUMPED"}, 
] }, 
{level: "Title 2", details: [ 
    {real: "There it is", fake: "THERE_IT_IS"}, 
    {real: "Car is flying", fake: "CAR_IS_FLYING"}, 
    {real: "Driving is fun", fake: "DRIVING_IS_FUN"} 
] }, 
{level: "Title 2", details: [ 
    {real: "There he is", fake: "THERE_WE_GO"}, 
    {real: "Where is the dog", fake: "WHERE_IS_THE_DOG"}, 
    {real: "The dog died", fake: "THE_DOG_DIED"}, 
    {real: "I am tired", fake: "I_AM_TIRED"}, 

]} 
]; 

由單詞 「the」

,使其返回

[ 
{level: "Title 1", details: [ 
    {real: "There we go", fake: "THERE_WE_GO"}, 
    {real: "The dog jumped", fake: "THE_DOG_JUMPED"}, 
] }, 
{level: "Title 2", details: [ 
    {real: "There it is", fake: "THERE_IT_IS"}, 
] }, 
{level: "Title 2", details: [ 
    {real: "There he is", fake: "THERE_WE_GO"}, 
    {real: "Where is the dog", fake: "WHERE_IS_THE_DOG"}, 
    {real: "The dog died", fake: "THE_DOG_DIED"}, 
]} 
]; 

注意,當這個詞過濾器 「的」我還想保留任何有「the」這個詞作爲其中的一部分的詞,例如「there」......我只是去檢查單詞「the」是否在「the」的對象的「真實」索引中細節的數組。

+0

這不是一個對象,而是一個對象數組。因此,下劃線過濾對你來說工作得很好。您當然需要編寫過濾功能。你有沒有做過任何可以顯示代碼的嘗試? –

+0

ES5中有一個內置的[* filter *](http://ecma-international.org/ecma-262/5.1/#sec-15.4.4.20),爲什麼你需要這樣的underscore.js? – RobG

回答

0

您可以使用filter,但你將不得不一旦它適用於每個內部列表,一旦外部列表:

var phrase = "the".toUpperCase(); 
return _.filter(_.map(data, function(item) { 
    return { 
     level: item.level, 
     details: _.filter(item.details, function(detail) { 
      return detail.fake.indexOf(phrase) > -1; 
     }) 
    }; 
}), function(item) { 
    return item.details.length > 0; 
}); 

從你的例子,我無法推斷是否需要在外部filter全部,或者您是否不想刪除具有空白詳細信息列表的項目。

0

這與普通的JavaScript的溶液:

var arr = [ 
    {level: "Title 1", details: [ 
     {real: "There we go", fake: "THERE_WE_GO"}, 
     {real: "Where is it", fake: "WHERE_IS_IT"}, 
     {real: "The dog jumped", fake: "THE_DOG_JUMPED"}, 
    ] }, 
    {level: "Title 2", details: [ 
     {real: "There it is", fake: "THERE_IT_IS"}, 
     {real: "Car is flying", fake: "CAR_IS_FLYING"}, 
     {real: "Driving is fun", fake: "DRIVING_IS_FUN"} 
    ] }, 
    {level: "Title 3", details: [ 
     {real: "There he is", fake: "THERE_WE_GO"}, 
     {real: "Where is the dog", fake: "WHERE_IS_THE_DOG"}, 
     {real: "The dog died", fake: "THE_DOG_DIED"}, 
     {real: "I am tired", fake: "I_AM_TIRED"}, 

    ]} 
]; 
function filterArr(arr, str) { 
    var ret = new Array(); 
    for (var i = 0; arr[i]; i++) { 
     var obj = arr[i].details; 
     ret[i] = new Object(); 
     ret[i]['level'] = arr[i].level; 
     ret[i]['details'] = []; 

     for (var j = 0; obj[j]; j++) { 
      if (obj[j].real.toLowerCase().indexOf(str.toLowerCase()) != -1) { 

       ret[i].details.push(obj[j]); 
      } 


     } 
    } 
    return ret; 
} 
console.log(filterArr(arr, 'the')); 
+0

你可以用'ret [i] = {level:arr [i] .level,details:[]};'替換3行。 :-) – RobG

0

這裏是另一個 「普通」 JavaScript的解決方案。它試圖最大限度地減少硬編碼的屬性,但可能不是真的有必要。

可以使用過濾的forEach地圖等,但一般普通的循環運行速度比嵌套迭代器快做在更少的代碼:

function filterOn(data, value) { 
    var re = new RegExp(value,'i'); 
    var result = []; 
    var details, keys, obj, temp; 

    for (var i=0, iLen=data.length; i<iLen; i++) { 
     temp = {level: data[i].level, details:[]}; 
     details = data[i].details; 

     for (var j=0, jLen=details.length; j<jLen; j++) { 
     obj = details[j]; 

     for (var p in obj) { 

      if (obj.hasOwnProperty(p) && re.test(obj[p])) { 
      temp.details.push(details[j]); 
      break; 
      } 
     } 
     } 
     if (temp.details.length) result.push(temp); 
    } 
    return result; 
    } 
+0

爲什麼在第三個循環中打破? – Hidran