如何限制每个功能的数量?

时间:2019-04-29 12:20:50

标签: javascript lodash

我有以下对象:

"data": [
  {
   "label": "dataName",
   "sections": [
     {
      "label": "label sections 1",
      "fields": [
         {
          "id": 1,
          "name": "field 1",
          "value": "value field 1"
         },
         {
          "id": 2,
          "name": "field 2",
          "value": "value field 2"
         }
        ]
      },
    {
      "label": "label sections 2",
      "fields": [
        {
         "id": 5,
         "name": "field 3",
         "value": "value field 3"
        }
       ]
     }
   ]

我想通过从每个字段中检索数据来创建一个新数组。

像这样:

  array [
      {id: field.id, name: field.name, value: field.value }
      {id: field.id, name: field.name, value: field.value }
  ]

我想我会像这样使用每个功能:

    _.each(data, function (elt) {
            _.each(elt.ections, function (elt) {
            ....
         })
     });

但是使用每个函数我应该将每个函数相乘。

是否有一种解决方案可以在不使用多个函数的情况下获得相同的结果?

如果您有解决方案?

私下

4 个答案:

答案 0 :(得分:2)

使用reduce方法:

var reduceSections = data.reduce((a,b) => (a.concat(b.sections)),[]);
var reduceFields = reduceSections.reduce((a,b) => (a.concat(b.fields)),[]);
var result = reduceFields;
console.log(result);

有关更多信息,请参见

演示

var data = [{
   "label": "dataName",
   "sections": [{
      "label": "label sections 1",
      "fields": [{
          "id": 1,
          "name": "field 1",
          "value": "value field 1"
      },{
          "id": 2,
          "name": "field 2",
          "value": "value field 2"
      }]
   },{
      "label": "label sections 2",
      "fields": [{
         "id": 5,
         "name": "field 3",
         "value": "value field 3"
      }]
   }]
}];
var reduceSections = data.reduce((a,b) => (a.concat(b.sections)),[]);
var reduceFields = reduceSections.reduce((a,b) => (a.concat(b.fields)),[]);
var result = reduceFields;
console.log(result);


  

唯一的缺点是,对原始数据对象进行变异将对数组中的结果进行变异。 (无浅层克隆)

根据应用程序的不同,可能不是,也可能不是。

如果要克隆对象:

var clone = result.map(obj => Object.assign({},obj));

有关更多信息,请参见

答案 1 :(得分:1)

当您已经在使用lodash时,就可以访问_.flatMap_.map_.clone

不幸的是,对于您的数据结构,需要对数据中的数组进行迭代,但是根据您要实现的目标,_.each可以有替代选择。

假设您想将fields中所有克隆的条目(嵌套在数组sections的每个条目中,嵌套在数组data的每个条目中)进行联接,您可以使用以下代码:

function cloneFields(elt) { return _.map(elt.fields, _.clone) }

var allClonedFields = _.flatMap(data, elt => {
  return _.flatMap(elt.sections, cloneFields);
});

函数cloneFields()在循环之外初始化以提高性能,因此不会在每次迭代时都创建该函数。

此代码将提取数据中的每个条目,然后从该条目中提取sections键中的每个条目,然后在fields键中返回每个条目的克隆,然后将它们连接到一个大数组中,得到以下结果:

[ { id: 1, name: 'field 1', value: 'value field 1' },
  { id: 2, name: 'field 2', value: 'value field 2' },
  { id: 5, name: 'field 3', value: 'value field 3' } ]

答案 2 :(得分:0)

如果我理解正确,则您正在尝试从数组中的每个元素获取fields属性。为此,请查看array.map()

使用array.map,您可以执行以下操作:

let array = data.map(x => x.fields);

或:

let array = data.map(x => (
    {id: x.fields.id,name: x.fields.name, value: x.fields.value }
));

https://www.w3schools.com/jsref/jsref_map.asp

答案 3 :(得分:0)

如果您不确切知道对象的“深度”如何,我建议您使用递归函数。这是我的建议:

function recursivlyCreateObject(data) {
    let result;
    if(Array.isArray(data)) {
        result = [];
        data.forEach(function(element) {
            result.push(recursivlyCreateObject(element));
        });
    } else {
        result = {};
        Object.keys(data).forEach(function(key) {
            result[key] = data[key];
        });
    }
    return result;
}

您可以here对其进行测试

编辑:请注意,这只不过是一个简单的console.log记录数据,但可以帮助您递归地迭代对象