在分层数组中深度查找、删除、更新

Deep Find, Remove, Update in a hierarchical array

假设我们有这样一棵树:

const items = [
    {
        "id": 1
    },
    {
        "id": 2,
        "items": [
            {
                "id": 3
            },
            {
                "id": 4,
                "items": []
            }
        ]
    }
];

我正在寻找一种通过其唯一 ID remove/update 项目的有效方法;主要问题是我们不知道项目的确切路径,更糟糕的是:树可能有 n 层,而我们只有一个 id。

删除节点及其后代

这是使用 flatMap 和相互递归的有效技术 -

  1. del 接受一个 数组 节点,t,一个查询,q,并在每个节点上调用 del1带有查询的节点
  2. del1 接受一个 单个 节点,t,一个查询,q,并在节点的 del 上调用 del项目

const del = (t = [], q = null) =>
  t.flatMap(v => del1(v, q))            // <-- 1

const del1 = (t = {}, q = null) =>
  q == t.id
    ? []
    : { ...t, items: del(t.items, q) }  // <-- 2

const data =
  [{id:1},{id:2,items:[{id:3},{id:4,items:[]}]}]

const result =
  del(data, 3)

console.log(result)

在输出中,我们看到 node.id 3 被删除了 -

[
  {
    "id": 1,
    "items": []
  },
  {
    "id": 2,
    "items": [
      {
        "id": 4,
        "items": []
      }
    ]
  }
]

如果我们只想删除父级但以某种方式将父级的 items 保留在树中怎么办?有没有不用相互递归的写法?在 .

中了解有关此技术的更多信息

一切都减少了

如果您知道 filter 但还没有使用过 flatmap,您可能会惊讶地发现 -

  1. filterflatmap
  2. 的特殊形式
  3. flatmapreduce
  4. 的特殊形式

const identity = x =>
  x

const filter = (t = [], f = identity) =>
  flatmap                                      // 1
    ( t
    , v => f(v) ? [v] : []
    )

const flatmap = (t = [], f = identity) =>
  t.reduce                                     // 2
    ( (r, v) => r.concat(f(v))
    , []
    )
    
const input =
  [ "sam", "alex", "mary", "rat", "jo", "wren" ]
  
const result =
  filter(input, name => name.length > 3)
  
console.log(result)
// [ "alex", "mary", "wren" ]