Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有没有一种简单的方法可以用Lodash映射嵌套数据?_Javascript_Functional Programming_Lodash_Pure Function - Fatal编程技术网

Javascript 有没有一种简单的方法可以用Lodash映射嵌套数据?

Javascript 有没有一种简单的方法可以用Lodash映射嵌套数据?,javascript,functional-programming,lodash,pure-function,Javascript,Functional Programming,Lodash,Pure Function,对于我当前的项目,我正在使用一个API,该API返回如下格式的数据: { groups: [ { items: [ { points: [ { name: "name1", ... }, { name: "name2", ... }, { name: "name3", ... }, ... ], ...

对于我当前的项目,我正在使用一个API,该API返回如下格式的数据:

{
  groups: [
    {
      items: [
        {
          points: [
            { name: "name1", ... },
            { name: "name2", ... },
            { name: "name3", ... },
            ...
          ],
          ...
        },
        ...
      ]
    },
    ...
  ],
  ...
};
我想创建一个纯函数,
mapValues
,它接受上述格式的对象,以及一个将每个
名称
映射到
的对象,并返回相同的结构,但每个
都包含与其
名称
对应的

例如,调用
mapValues(数据,{name1:“value1”,name2:“value2”,name3:“value3”})
应返回以下内容:

{
  groups: [
    {
      items: [
        {
          points: [
            { name: "name1", value: "value1", ... },
            { name: "name2", value: "value2", ... },
            { name: "name3", value: "value3", ... },
            ...
          ],
          ...
        },
        ...
      ]
    },
    ...
  ],
  ...
};
这是我的第一张通行证:

function mapValues(data, values) {
  return _.extend({}, data, {
    groups: _.map(ui.groups, (group) => {
      return _.extend({}, group, {
        items: _.map(group.items, (item) => {
          return _.extend({}, item, {
            points: _.map(item.points, (point) => {
              return _.extend({ value: values[point.name] }, point);
            })
          });
        })
      });
    })
  });
}
这是可行的,但有相当多的嵌套重复代码。在第二次尝试中,我尝试递归

function mapValues(data, values) {
  return (function recursiveMap(object, attributes) {
    if (attributes.length === 0) { return _.extend({ value: values[object.name] }, object); }
    let key = attributes[0];
    return _.extend({}, object, {
      [key]: _.map(object[key], child => recursiveMap(child, attributes.slice(1)))
    });
  })(ui, ["groups", "items", "points"]);
}
这也行得通,但很难阅读,也不是很简洁


是否有更干净的方法使用Lodash递归映射对象?理想情况下,我正在寻找一种功能性的方法。

我知道您想要Lodash,但不久前我遇到了同样的问题,我提出了这个方法,我正在使用由创建的伟大工具。它非常简单,但很有用。您可以使用
对象将此函数调整为纯函数。分配
,接受关键参数并根据需要调整它。你明白了

function mapValues(data, values) {
  var iterator = new RecursiveIterator(data);
  for(let {node} of iterator) {
    if(node.hasOwnProperty('name')) {
        node.value = values[node.name];
    }
  }
  return data;
}

这里有一种方法可以使用
对象来完成。分配
而不使用奇特的函数

var data = <your data here>;
var values = <your mapped values>;

data.groups.items.points.map(p=>
  Object.assign(p, {value: values[p.name]})
);

谢谢你的回复!我认为这里的问题是
也是数组,您的解决方案是将它们作为对象处理。感谢您的回复!我喜欢递归迭代器的概念,但是这个解决方案似乎可以在适当的位置修改值,我希望得到一个纯函数式的解决方案。纯,我的意思是:您可以始终使用
对象。分配
以避免数据对象发生变化,并创建这个“复制”对象的迭代器,然后返回它。
var newData = Object.assign({}, data,
  {groups:
    {items:
      {points: data.groups.items.points.map(p=>
        Object.assign({}, p, {value: values[p.name]})
      )}
    }
  }
);