更改嵌套数组中的对象属性

时间:2020-07-14 15:10:42

标签: javascript arrays object recursion nested

我有一个数组:

   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)
    }
  }
}

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

2 个答案:

答案 0 :(得分:0)

尝试使用数组映射方法:

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));

答案 1 :(得分:0)

我将分解从执行数据操作的代码中找到后代列表的递归代码。这是一种可能性:

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 是向changeBranch应用将visible设置为false的函数的结果。这是您要寻找的最终功能。

请注意,如果您的列表是循环的而不是分层的,则此方法将无效。您的堆栈可能会溢出。