2015-04-25 95 views
3

这是我的数据对象会是什么样子http://jsfiddle.net/303tpLtz/1嵌套分类搜索使用下划线JS

正如你可以看到here里面有分类类别所以,问题是当搜索完成

必须考虑我可以用_.findWhere(result.response.categories, {name: 'Arts & Entertainment'})

找到类别的顶级名称,但问题是,当我需要找到提供的请求中提到的某些东西,例如,如果我需要找到一个餐厅,里面食品>

任何人都可以帮助我的深度搜索功能吗?

我纠结的解决方案jsFiddle

function findDeep(cats, attrs) { 
    _.each(cats, function(data, i) { 
     var copy = data; 
     // delete copy.categories; 
     newArr.push(copy); 
     _.each(data.categories, function(newObj) { 
      var copy2 = newObj; 
      // delete copy2.categories; 
      newArr.push(copy2) 

      if (newObj.categories) { 
       _.each(newObj.categories, function(otherObj) { 
        var copy3 = otherObj; 
        // delete copy3.categories; 
        newArr.push(copy3) 
       }) 
      } 
     }) 
    }); 

    return _.findWhere(newArr, attrs) || null; 
} 
+0

猜测:[Underscore.js - 以嵌套的Json过滤(https://stackoverflow.com/questions/22994658/underscore-js-filtering-in-a-nested-json)。互联网搜索:_'Underscore.js - 在嵌套的Json中过滤__。是更多的猜测 –

+0

没有@RyanVincent,如果你看起来很近,请在我的类别里有更多的json对象,当搜索完成时需要考虑https://gist.github.com/sahanDissanayake/b29c913a00d33bffc67f#file-gistfile1-js- L199 – Sahan

回答

1

这个数据的问题是每个节点可能需要进一步检查,这意味着你不能过滤器巧妙地应用到每一个项目,因为对跳过项目本身可能有嵌套的类别,你需要检查。

但是,使用普通的javascript或者在_.reducerecursive magic的帮助下,我们只需要一点点代码即可完成工作。

jsFiddle

function findMatchingCategories(cats, attrs) { 
    return _.filter(extractCategories(cats), attrs); 

    function extractCategories(cats) { 
     return _.reduce(cats, function (result, value) { 
      return result.concat([value]).concat(value.categories ? extractCategories(value.categories) : []); 
     }, []); 
    } 
} 

console.log(findMatchingCategories(data, { name: 'Tunnel' })); 

为了解释:

_.reduce让我们你通过一组数据,并保持一个逐步“减少”数据变量的轨道。在我们的例子中,我们将一组类别减少到名为result的新数组,该数组只包含所有嵌套类别。为了确保我们检查所有嵌套类别,我们递归调用extractCategories并使用它的结果将其添加到简化结果数组中。

最后,我们留下的是所有类别,嵌套与否,然后我们根据attr匹配进行过滤。


更高性能的版本,用更少的连接:

jsFiddle

function findMatchingCategories(cats, attrs) { 
    return _.filter(extractCategories(cats, []), attrs); 

    function extractCategories(currentCats, allCats) { 
     _.each(currentCats, function (value) { 
      allCats.push(value); 
      if (value.categories) { 
       extractCategories(value.categories, allCats); 
      } 
     }, []); 
     return allCats; 
    } 
} 

console.log(findMatchingCategories(data, { name: 'Tunnel' })); 

我们去表现的越少,简洁的代码变得。

Performance comparison of all three approaches

+0

嘿,即时通讯使用lodash V2.4.1 https://github.com/lodash/lodash/blob/2.4.1/doc/README.md _.isMatch不存在,还有什么我可以使用? – Sahan

+0

我以为你在用下划线......你换了吗?无论如何,它仍然可以使用'_.where'或'_。过滤器“而不是'_.isMatch'。我更新了我的答案。 –

+0

好像我的功能比你的超快?!?!? http://jsfiddle.net/a3wevt35/4/ – Sahan