Обход дерева, как массив - PullRequest
       2

Обход дерева, как массив

0 голосов
/ 21 сентября 2018

У меня есть массив, который выглядит как древовидная структура.Это массив объектов, где у объектов есть массив потомков, а у потомков - массив потомков.Ниже приведен пример.Я пытался использовать рекурсию в задаче, но не смог получить желаемый результат.

[
    {
      parentId: null,
      children: [
        {
          parentId: 267,
          children: [
            {
              parentId: 268,
              children: [
                {
                  parentId: 270,
                  children: null,
                }
              ],
            },
            {
              parentId: 268,
              children: [
                {
                  parentId: 269,
                  children: null,
                }
              ],
            }
          ],
        }
      ],
    },
   ...
   ...
  ];

Я хотел бы пройти через этот массив, и в каждый объект мне нужно добавить ключ и значение.

Например, open: 'fa fa-open'

Каждый объект в результирующем массиве должен иметь вышеуказанный ключ.

Ответы [ 4 ]

0 голосов
/ 21 сентября 2018

Этот тип проблемы идеально подходит для изучения взаимной рекурсии.

Сначала мы сделаем способ traverse одного node и его children, используя функцию более высокого порядка f-

const traverse = (f, { children = [], ...node }) =>
  f ({ ...node, children: children.map (c => traverse (f, c)) })

Например, добавить свойство hello, установленное на 'world' для каждого узла -

traverse
  ( node => ({ ...node, hello: 'world' })
  , { a: 1, children: [ { b: 2 } ] }
  )

// { a: 1
// , children:
//     [ { b: 2
//       , children: []
//       , hello: 'world'
//       }
//     ]
//  }

Но это работает только для одного узла,У вас есть массив узлов, поэтому -

const traverseAll = (f, nodes = []) =>
  nodes.map (node => traverse (f, node))

Когда вы оглядываетесь назад на traverse, мы видим, что повторились ( полужирным ) -

const traverse = (f, { children = [], ...node }) =>
  f ({ ...node, children: <b>children.map (c => traverse (f, c))</b> })

const traverseAll = (f, nodes = []) =>
  <b>nodes.map (node => traverse (f, node))</b>

Используя взаимно рекурсивное определение, мы пишем гармоничную пару -

const traverseAll = (f, nodes = []) =>
  nodes.map (node => <b>traverse (f, node)</b>)

const traverse = (f, { children = [], ...node }) =>
  f ({ ...node, children: <b>traverseAll (f, children)</b> })

Проверьте всю программу в вашем браузере ниже -

const traverseAll = (f, nodes = []) =>
  nodes.map (node => traverse (f, node))

const traverse = (f, { children = [], ...node }) =>
  f ({ ...node, children: traverseAll (f, children) })

const nodes =
  [ { id: 1
    , children:
        [ { id: 2
          , children: []
          }
        , { id: 3
          , children:
              [ { id: 4
                , children: []
                }
              ]
          }
        ]
     }
   , { id: 5
     , children: []
     }
   ]
   
console.log
  ( traverseAll
      ( node => ({ ...node, open: 'fa fa-open' })
      , nodes
      )
  )

// [ { id: 1
//   , children: 
//       [ { id: 2, children: [], open: 'fa fa-open' },
//         { id: 3
//         , children:
//             [ { id: 4
//               , children: []
//               , open: 'fa fa-open'
//               }
//             ]
//         , open: 'fa fa-open'
//         }
//       ]
//   , open: 'fa fa-open'
//   }
// , { id: 5
//   , children: []
//   , open: 'fa fa-open'
//   }
// ]
0 голосов
/ 21 сентября 2018

enter image description here Пожалуйста, посмотрите на код в ссылке ниже, он рекурсивно пересекает все дочерние элементы и вставляет открытые: 'fa fa-open' https://codesandbox.io/s/o4jvxloy7q

0 голосов
/ 21 сентября 2018

Вы можете создать рекурсивную функцию с циклом forEach, который принимает данные и объект и назначает этот объект каждому объекту в ваших данных.

const data = [{"parentId":null,"children":[{"parentId":267,"children":[{"parentId":268,"children":[{"parentId":270,"children":null}]},{"parentId":268,"children":[{"parentId":269,"children":null}]}]}]}]

function add(data, obj) {
  data.forEach(e => {
    Object.assign(e, obj);
    if (e.children) add(e.children, obj)
  })
}

add(data, {open: 'fa fa-open'})
console.log(data)
0 голосов
/ 21 сентября 2018

let data = [
  {
    parentId: 123,
    children: [],
  },
  {
    parentId: 345,
    children: [],
  },
  {
    parentId: 1567,
    children: [],
  },
];

data.forEach(item => item.open = "new value")
console.log(data)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...