Transform all child objects using recursive reduce in ES6

时间:2019-04-17 01:06:56

标签: javascript node.js ecmascript-6 functional-programming reduce

I'm trying to create a set of reducers in order to change an attribute of all objects in a nested list.

The input payload looks like the following:

const payload = [
  {
    name: "Peter",
    children: [
      {
        name: "Sarah",
        children: [
          {
            name: "Sophie",
            children: [
              {
                name: "Chris"
              }
            ]
          }
        ]
      }
    ]
  }
];

I now want to change the name attribute of all elements and child elements.

const mapJustNickname = elem => {
  return {
    ...elem,
    nickname: elem.name + "y"
  };
};

How do I use this map function recursively on all child elements?

I found a way to do this by putting the the recursion within the same mapping function.

const mapToNickname = (elem) => {
    return {
    nickname: elem.name +'y',
    children: elem.children && elem.children.map(mapToNickname)
  }
}

console.log(payload.map(mapToNickname));

But I'd like to have the mapping of the name separated from the recursion (for reasons of keeping the mapping functions as simple as possible) and being able to chain them later. Is it somehow possible to do this with two reducers and then chaining them together?

2 个答案:

答案 0 :(得分:2)

让我们从严格定义数据结构开始:

data Person = Person { name :: String, nickname :: Maybe String }

data Tree a = Tree { value :: a, children :: Forest a }

type Forest a = [Tree a]

type FamilyTree = Tree Person

type FamilyForest = Forest Person

现在,我们可以创建mapTreemapForest函数:

const mapTree = (functor, { children=[], ...value }) => ({
    ...functor(value),
    children: mapForest(functor, children)
});

const mapForest = (functor, forest) => forest.map(tree => mapTree(functor, tree));

// Usage:

const payload = [
  {
    name: "Peter",
    children: [
      {
        name: "Sarah",
        children: [
          {
            name: "Sophie",
            children: [
              {
                name: "Chris"
              }
            ]
          }
        ]
      }
    ]
  }
];

const functor = ({ name }) => ({ name, nickname: name + "y" });

const result = mapForest(functor, payload);

console.log(result);

希望有帮助。

答案 1 :(得分:1)

创建一个递归映射函数,该函数映射一个项目及其子项(如果存在)。现在,您可以为while (!is.eof()){ 提供所需的ever转换函数,而该转换程序不需要处理树的递归性质。

recursiveMap