Чтобы сделать это для любого уровня вложенности, мы можем использовать довольно простой рекурсивный подход:
const transform = (xs) =>
xs .map (({children, ...rest}) => ({
elem: {
...rest,
...(children ? {children: transform (children)} : {})
}
}))
Но я думаю, что один уровень абстракции значительно улучшает это. Если мы отделим бит, который оборачивает узел в структуре {elem: ...}
, от бита, который применяет это рекурсивно, наш код будет и более простым, и более пригодным для повторного использования. Его проблемы лучше разделены. Так что я, вероятно, написал бы это так:
const mapDeep = (fn) => (xs) =>
xs .map (({children, ...rest}) => fn ({
...rest,
...(children ? {children: mapDeep (fn) (children)} : {})
}))
const data = [
{name:"name1"},
{name:"name2"},
{name:"name3", children : [
{id: "1"},
{id: "2", children: [ {foo: "bar"}, {foo: "baz"} ]}
]}
]
const wrapInElem = (node) => ({elem: node})
console .log (mapDeep (wrapInElem) (data))
И, конечно, передав только mapDeep
только функцию, мы получаем функцию многократного использования, которая делает то, что вы хотите:
const transform = mapDeep (wrapInElem)
// or, using an anonymous function instead
// const transform = mapDeep (node => ({elem: node}))
// ...
transform (data)