递归地找到孩子的孩子并删除

Chr*_*uru 0 javascript arrays recursion

我有一个有孩子的孩子的数组,一切都由parentId相关。

例:

[
{id: 1, parentid:0},{id: 2, parentid:1},
{id: 3, parentid:2},{id: 4, parentid:2},{id: 10, parentid:4},
{id: 5, parentid:0},{id: 6, parentid:5},{id: 7, parentid:7}
]
Run Code Online (Sandbox Code Playgroud)

我想使用Id:1及其所有相关子对象删除该对象。所以那是这些对象

{id: 1, parentid:0},{id: 2, parentid:1},
{id: 3, parentid:2},{id: 4, parentid:2},{id: 10, parentid:4}

Run Code Online (Sandbox Code Playgroud)

Tha*_*you 5

这是您可以使用递归实现的一种实用方法。带编号的项目符号点与下面的代码中带编号的注释匹配。

  1. (基本)没有,node因此没有任何可处理的东西;返回结果r
  2. (归纳法)至少有一个节点。如果节点的idparentid在集合中s,则找到匹配的节点。将节点添加id到集合中,并从部分结果r和其余节点开始搜索more
  3. (归纳法)至少有一个节点,它与我们要搜索的ID不匹配。将节点附加到结果,然后继续搜索more节点。

const removeFamily =
  ( id = 0
  , [ node, ...more ] = []
  , s = new Set ([ id ])
  , r = []
  ) =>
    node === undefined
      ? r                               // 1
      : s .has (node.id) || s .has (node.parentid)
          ? removeFamily                // 2
              ( id
              , [ ...r, ...more ]
              , s .add (node.id)
              , []
              )
          : removeFamily                // 3
              ( id
              , more
              , s
              , [ ...r, node ]
              )

const nodes =
  [ { id: 1, parentid: 0 }
  , { id: 2, parentid: 1 }
  , { id: 3, parentid: 2 }
  , { id: 4, parentid: 2 }
  , { id: 10, parentid: 4 }
  , { id: 5, parentid: 0 }
  , { id: 6, parentid: 5 }
  , { id: 7, parentid: 7 }
  ]

const newNodes =
  removeFamily (1, nodes)

console .log (newNodes)
// [ { id: 5, parentid: 0 }
// , { id: 6, parentid: 5 }
// , { id: 7, parentid: 7 }
// ]
Run Code Online (Sandbox Code Playgroud)

在这里用if语句重写它,如果可以帮助您更好地看待它,

const removeFamily =
  ( id = 0
  , [ node, ...more ] = []
  , s = new Set ([ id ])
  , r = []
  ) =>
  { if (node === undefined)
      return r               // 1
    else if (s .has (node.id) || s .has (node.parentid))
      return removeFamily    // 2
        ( id
        , [ ...r, ...more ]
        , s .add (node.id)
        , []
        )
    else
      return removeFamily    // 3
       ( id
       , more
       , s
       , [ ...r, node ]
       )
  }
Run Code Online (Sandbox Code Playgroud)

这是一个使用泛型loop/ recur接口的堆栈安全变体。即使节点列表可以包含数百万个节点,此版本也可以使用。它还具有稍微更好的公共接口,因为只有两(2)个参数可以在呼叫站点进行配置-

const removeFamily =
  ( id = 0
  , [ node, ...more ] = []
  , s = new Set ([ id ])
  , r = []
  ) =>
  { if (node === undefined)
      return r               // 1
    else if (s .has (node.id) || s .has (node.parentid))
      return removeFamily    // 2
        ( id
        , [ ...r, ...more ]
        , s .add (node.id)
        , []
        )
    else
      return removeFamily    // 3
       ( id
       , more
       , s
       , [ ...r, node ]
       )
  }
Run Code Online (Sandbox Code Playgroud)