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

Mir*_*lic 16 javascript underscore.js lodash

我有这个数组:

[
    {
        id: 1,
        name: 'test 1',
        children: []
    },
    {
        id: 2,
        name: 'test 2',
        children: [
            {
                id: 4,
                name: 'test 4'
            }
        ]
    },
    {
        id: 3,
        name: 'test 3',
        children: []
    }
]
Run Code Online (Sandbox Code Playgroud)

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

例如,搜索id = 3,应返回test 3对象,并搜索id = 4应返回test 4对象.

Ada*_*uch 31

使用lodash,你可以这样做:

_(data)
    .thru(function(coll) {
        return _.union(coll, _.pluck(coll, 'children'));
    })
    .flatten()
    .find({ id: 4 });
Run Code Online (Sandbox Code Playgroud)

这里,thru()用于初始化包装值.它返回原始数组和嵌套子类的并集.然后使用flatten()展平此数组结构,以便您可以找到()项目.

  • 优秀!对于lodash v4.0,用`map`替换`pluck`. (4认同)
  • 请记住,此实现仅深入一层。如果您的树超过一层深,它将无法按预期工作。 (2认同)
  • 如果我们还有 1 个嵌套子级需要查找,则此代码不起作用 (2认同)

Kir*_*ril 5

这是一个非常简单的树遍历任务。解决它的最简单方法是递归(链接到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;
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

更新:

要查找所有匹配项 - 稍微修改的函数(上面的 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;
}
Run Code Online (Sandbox Code Playgroud)


Ric*_*tte 5

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])
Run Code Online (Sandbox Code Playgroud)