【问题标题】:Change object property in nested array更改嵌套数组中的对象属性
【发布时间】:2020-11-03 23:19:24
【问题描述】:

我有一个数组:

   const array = [
      { id: 1, parent_id: 0, visible: true },
      { id: 2, parent_id: 0, visible: true },
      { id: 3, parent_id: 1, visible: true },
      { id: 4, parent_id: 3, visible: true },
      { id: 5, parent_id: 4, visible: true },
      { id: 6, parent_id: 4, visible: true },
      { id: 7, parent_id: 3, visible: true },
      { id: 8, parent_id: 2, visible: true }
    ]

我想创建一个带有参数 ID 和 ARRAY 的函数,该函数返回新数组,此 ID 为 VISIBLE = FALSE,每个嵌套的子节点都为 PARENT_ID。

我的努力是这样的

const result = []

const findFitstHandler = (id, arr) => {
  let j
  for (let i in arr) {
    if (arr[i].id === id) {
      result.push(arr[i].id)
      j = arr[i].id
    }
  }
  findNested(j, arr)

  return array.map(item => {
    if (result.includes(item.id)) {
      return {
        ...item,
        visible: false
      }
    } else {
      return item
    }
  })
}

const findNested = (id, arr) => {
  for (let i in arr) {
    if (arr[i].parent_id === id) {
      result.push(arr[i].id)
      findNested(arr[i].id, arr)
    }
  }
}

我确信有一个更优雅的解决方案。请帮帮我

【问题讨论】:

    标签: javascript arrays object recursion nested


    【解决方案1】:

    尝试使用数组映射方法:

    const array = [
          { id: 1, parent_id: 0, visible: true },
          { id: 2, parent_id: 0, visible: true },
          { id: 3, parent_id: 1, visible: true },
          { id: 4, parent_id: 3, visible: true },
          { id: 5, parent_id: 4, visible: true },
          { id: 6, parent_id: 4, visible: true },
          { id: 7, parent_id: 3, visible: true },
          { id: 8, parent_id: 2, visible: true }
        ];
        
    const getNewArray = (id, items) => items.map(item => {
       if ([item.id, item.parent_id].includes(id)) {
          item.visible = false;
       }
       
       return item;
    });    
    
    console.log(getNewArray(4, array));

    【讨论】:

      【解决方案2】:

      我会将用于查找后代列表的递归代码与进行数据操作的代码分开。这是一种可能性:

      const descendants = (array, root) => 
        [
          root, 
          ...array .filter (({parent_id}) => parent_id == root) 
                   .flatMap (({id}) => descendants (array, id))
        ]
      
      const changeBranch = (fn) => (array, root, keys = descendants (array, root)) =>
        array .map (element => keys .includes (element .id) ? fn (element) : element)
      
      const makeInvisible = changeBranch (
        ({visible, ...rest}) => ({...rest, visible: false})
      )
      
      const array = [{ id: 1, parent_id: 0, visible: true }, { id: 2, parent_id: 0, visible: true }, { id: 3, parent_id: 1, visible: true }, { id: 4, parent_id: 3, visible: true }, { id: 5, parent_id: 4, visible: true }, { id: 6, parent_id: 4, visible: true }, { id: 7, parent_id: 3, visible: true }, { id: 8, parent_id: 2, visible: true }];
          
      console .log (makeInvisible (array, 4))
      
      console .log (makeInvisible (array, 2))
      .as-console-wrapper {min-height: 100% !important; top: 0}

      descendants 查找所提供的根 id 的 id 以及在您的数组中从它派生的所有节点。

      changeBranch 接受一个函数来转换一个节点并返回一个函数,该函数接受一个数组和根 id,并返回一个包含应用该函数的结果的新数组(当节点是根的后代)或原始值(如果不是)。

      makeInvisible 是将visible 设置为false 的函数应用于changeBranch 的结果。这是您要寻找的最终功能。

      请注意,如果您的列表是循环的而不是分层的,这将不起作用。您的堆栈可能会溢出。

      【讨论】:

        猜你喜欢
        • 2021-10-27
        • 2019-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-14
        • 2013-10-11
        • 1970-01-01
        相关资源
        最近更新 更多