2014-06-24 44 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