Javascript 在数组和嵌套子数组中搜索 lodash 属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30714938/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:37:46  来源:igfitidea点击:

lodash property search in array and in nested child arrays

javascriptunderscore.jslodash

提问by Mirza Delic

I have this array:

我有这个数组:

[
    {
        id: 1,
        name: 'test 1',
        children: []
    },
    {
        id: 2,
        name: 'test 2',
        children: [
            {
                id: 4,
                name: 'test 4'
            }
        ]
    },
    {
        id: 3,
        name: 'test 3',
        children: []
    }
]

How can I filter by the idproperty in both this array andthe nested childrenarrays?

如何id按此数组嵌套children数组中的属性进行过滤?

For example, searching for id = 3, should return the test 3object, and searching for id = 4should return the test 4object.

例如,搜索id = 3, 应该返回test 3对象,搜索id = 4应该返回test 4对象。

回答by Adam Boduch

Using lodash, you can do something like this:

使用 lodash,您可以执行以下操作:

_(data)
    .thru(function(coll) {
        return _.union(coll, _.map(coll, 'children') || []);
    })
    .flatten()
    .find({ id: 4 });

Here, thru()is used to initialize the wrapped value. It's returning the union of the original array, and the nested children. This array structure is then flattened using flatten(), so you can find()the item.

在这里,thru()用于初始化包装值。它返回原始数组和嵌套子数组的联合。然后使用flatten() 将这个数组结构展平,以便您可以find()项目。

回答by Kiril

That's a very simple tree traversaltask. The easiest way to solve it is recursion (link to jsbin). It will work with any depth (with recursion limit of course) and it's one of the fastest ways with the worst complexity O(n):

这是一个非常简单的树遍历任务。解决它的最简单方法是递归(链接到jsbin)。它适用于任何深度(当然有递归限制),并且它是最快的方法之一,具有最差的复杂度 O(n):

function find(id, items) {
  var i = 0, found;

  for (; i < items.length; i++) {
    if (items[i].id === id) {
      return items[i];
    } else if (_.isArray(items[i].children)) {
      found = find(id, items[i].children);
      if (found) {
        return found;
      }
    }
  }
}

Update:

更新:

To find all matches - a slightly modified function (jsbin link above is updated):

要查找所有匹配项 - 稍微修改的函数(上面的 jsbin 链接已更新):

function findAll(id, items) {
  var i = 0, found, result = [];

  for (; i < items.length; i++) {
    if (items[i].id === id) {
      result.push(items[i]);
    } else if (_.isArray(items[i].children)) {
      found = findAll(id, items[i].children);
      if (found.length) {
        result = result.concat(found);
      }
    }
  }

  return result;
}

回答by Richard Ayotte

Another lodashoption with children key and unlimited levels deep.

lodash一种带有儿童键和无限深度的选项。

const flattenItems = (items, key) => {
    return items.reduce((flattenedItems, item) => {
        flattenedItems.push(item)
        if (Array.isArray(item[key])) {
            flattenedItems = flattenedItems.concat(flattenItems(item[key], key))
        }
        return flattenedItems
    }, [])
}

const item = find(flattenItems(items, 'children'), ['id', 4])