2015-10-22 94 views
0

我正在尝试编写一个筛选器函数,它将一个对象作为参数并将查询字符串作为其第二个参数。该函数应返回匹配查询字符串的对象中的所有值的列表。通过对象进行筛选

例如

var data = [{ 
    label: 'Cars', 
    children: [{ 
     label: 'Volkswagan', 
     children: [{ 
      label: 'Passat' 
     }] 
    }, { 
     label: 'Toyota' 
    }] 
}, { 
    label: 'Fruits', 
    children: [{ 
     label: 'Grapes' 
    }, { 
     label: 'Oranges' 
    }] 
}]; 

function filter(data, query){} 
filter(data,'ra'); //['Grapes', 'Oranges'] 

我的问题是如何解决的每个索引对象嵌套的“孩子”属性?

回答

1

你想用递归这一点。

function filter(data, query){ 
    var ret = []; 

    data.forEach(function(e){ 
     // See if this element matches 
     if(e.label.indexOf(query) > -1){ 
      ret.push(e.label); 
     } 

     // If there are children, then call filter() again 
     // to see if any children match 
     if(e.children){ 
      ret = ret.concat(filter(e.children, query)); 
     } 
    }); 

    return ret; 
} 
+0

哦,这个男人这么漂亮,我怎么没有想到递归谢谢 – RRP

+0

不客气! :-) –

1

尝试使用基于每个属性的数据类型的递归调用。例如,在嵌套属性是数组的情况下,您需要对该数组的每个元素调用过滤器。在嵌套元素是对象的情况下类似的逻辑,你想看看每个属性和调用过滤器。我写这篇即兴的,所以我没有测试所有的角落案件,但它的工作原理为您的测试例如:

var results = []; 
filter(data,'ra'); //['Grapes', 'Oranges'] 
console.log(results); 
function filter(data,query){ 
    for(var prop in data){ 
    //array 
    if(Array.isArray(data[prop])){ 
     for(var i = 0; i < data[prop].length; i++){ 
     filter(data[prop][i],query); 
     } 
    } else if (typeof data[prop] === "object"){ 
    filter(data[prop],query); 
    } else if(typeof data[prop] === "string"){ 
     if(data[prop].indexOf(query) > -1){ 
     results.push(data[prop]); 
     } 
    } 
    } 
}