【问题标题】:Recursively remove object from nested array从嵌套数组中递归删除对象
【发布时间】:2020-05-07 11:00:58
【问题描述】:

我有这样的数组。可以无限嵌套

const myArray = [
  {
   id: 1, 
   children: [
              { 
                id: 3,
                children: []
              }
             ]
  },
  {
   id: 2, children: []
  }
]

请帮我按 id 删除任何对象并返回没有它的新数组。

【问题讨论】:

    标签: javascript arrays object recursion


    【解决方案1】:

    recursiveRemove 函数将递归地从数组中删除元素并返回新列表。

    map 函数创建数组中项目的副本,如果您不需要保留原始数组的健全性,可以删除 map。

    function recursiveRemove ( list, id ) {
        return list.map ( item => { return {...item} }).filter ( item => {
            if ( 'children' in item ) {
                item.children = recursiveRemove ( item.children, id );
            }
            return item.id !== id;
        });
    }
    const test1 = recursiveRemove ( myArray, 1);
    const test2 = recursiveRemove ( myArray, 2);
    const test3 = recursiveRemove ( myArray, 3);
    

    【讨论】:

      【解决方案2】:

      使用数组方法和递归函数:

      function fn(arr, id) {
        return arr
          .filter((el) => el.id !== id)
          .map((el) => {
            if (!el.children || !Array.isArray(el.children)) return el;
            el.children = fn(el.children, id);
            return el;
          });
      }
      
      const myArray = [
        {
          id: 1,
          children: [
            {
              id: 3,
              children: [],
            },
          ],
        },
        {
          id: 2,
          children: [],
        },
      ];
      
      console.log(fn(myArray,1))
      console.log(fn(myArray,2))
      console.log(fn(myArray,3))

      【讨论】:

        【解决方案3】:
        function removeFromArrayOfObj (array, idToRemove) {
          for (const [i, e] of array.entries()) {
            if (e.id === idToRemove) {
             array.splice(i, 1)
             continue
            }
           if (e.children) {
             removeFromArrayOfObj(e.children, idToRemove)
            }
         }
         return array
        }
        

        【讨论】:

          【解决方案4】:

          您可以解构对象并将idchildren 从对象中取出。然后用前一个对象的其余部分获取一个新对象并映射子对象。

          const
              withoutId = ({ id, children, ...o }) => ({ ...o, children: children.map(withoutId) }),
              array = [{ id: 1, children: [{ id: 3, children: [] }] }, { id: 2, children: [] }],
              without = array.map(withoutId);
          
          console.log(without);

          【讨论】:

          • 操作员问:Please, help me to remove any object by id...
          【解决方案5】:

          对我来说,将递归遍历和过滤从删除某个 id 的实际细节中分离出来是有意义的。所以我会写一个更通用的filterDeep 函数,它只保留那些谓词为真的对象,递归到children 节点。

          然后我们可以为它提供一个谓词来检查一个项目是否与特定的 id 匹配。或者更确切地说,由于我们要删除那些匹配的,我们的谓词实际上检查我们的节点是否不匹配 id。

          这是该想法的实现:

          const filterDeep = (pred) => (xs) =>
            xs .flatMap (x => pred (x)
              ? [{... x, children: filterDeep (pred) (x .children || [])}] 
              : []
            )
            
          const removeId = (id) =>  
            filterDeep (x => x.id !== id)
          
          const myArray = [{id: 1, children: [{id: 3, children: []}]}, {id: 2, children: []}]
          
          console .log (removeId (1) (myArray))
          console .log (removeId (2) (myArray))
          console .log (removeId (3) (myArray))
          console .log (removeId (42) (myArray))
          .as-console-wrapper {min-height: 100% !important; top: 0}

          这将包括一个children 节点,即使原始节点没有。如果我们只想在有一个开头时才包含它,我们可以将其更改为如下内容:

          const filterDeep = (pred) => (xs) =>
            xs .flatMap (x => pred (x) 
              ? [{
                  ... x, 
                  ... (x.children ? {children: filterDeep (pred) (x .children || [])} : {})
                }] 
              : []
            )
          

          或者更复杂一点,我们可以选择仅当 children 节点在父节点中可用并且结果非空时才包含它。这留给读者作为练习。 :-)

          【讨论】:

          • 这个问题出现的最佳时机!和完美的搭配!
          【解决方案6】:

          啊,作业问题。

          • 写“kill_entries_with_id(child_array, id_to_kill)”。对于子数组的每个元素,如果它的 id 匹配,它应该del 元素。否则,它应该使用元素的子元素递归调用自身。
          • 请注意,您应该按索引向后遍历数组,这样您就不必担心删除元素会破坏循环。考虑list(range(10,-1,-1)

          【讨论】:

            猜你喜欢
            • 2021-04-24
            • 1970-01-01
            • 1970-01-01
            • 2012-03-15
            • 2020-12-07
            • 2021-12-28
            • 2019-05-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多