Изменить свойство объекта во вложенном массиве - PullRequest
1 голос
/ 14 июля 2020

У меня есть массив:

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

Я хочу создать функцию с идентификатором аргументов и ARRAY, которая возвращает новый массив с 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 голосов
/ 14 июля 2020

Я бы разделил рекурсивный код, который находит список потомков из кода, который выполняет манипуляции с данными. Вот одна возможность:

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 находит идентификаторы предоставленного root id и всех узлов-потомков внутри вашего массива.

changeBranch принимает функцию для преобразования узла и возвращает функцию, которая принимает массив и root id, и возвращает новый массив, содержащий либо результат применения этой функции (когда узел является потомком root) или исходного значения (если это не так.)

makeInvisible является результатом применения к changeBranch функции, которая устанавливает * От 1023 * до false. Это последняя функция, которую вы ищете.

Обратите внимание, что если ваш список циклический c, а не иерархический, это не сработает. Ваш стек, вероятно, переполнится.

0 голосов
/ 14 июля 2020

Попробуйте использовать метод карты массива:

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));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...