node js从对象数组创建特定模式的对象

时间:2018-06-01 09:23:11

标签: javascript node.js

我在使用对象数组创建对象时遇到for循环中的一些问题。我在节点js app中有一个数组:

[
        {
            "Material": "113/133",
            "Name": [
                {
                    "name": "WELD1",
                    "value": 27520
                },
                {
                    "name": "WELD2",
                    "value": 676992
                },
                {
                    "name": "WELD3",
                    "value": 421
                }
            ]
        },
        {
            "Material": "150/300",
            "Name": [
                {
                    "name": "WELD1",
                    "value": 1441
                },
                {
                    "name": "WELD2",
                    "value": 555
                },
                {
                    "name": "WELD3",
                    "value": 100992
                }
            ]
        }
    ]

我想返回像这样的对象,其中包含所有Material作为数组,Name和对象数组中的值,如下所示:

{
    Material: ["113/133", "150/300"],
    datasets: [
        {
            label: "WELD1",
            data: [27520,1441]
        },
        {
            label: "WELD2",
            data: [676992,555]
        },
                {
            label: "WELD3",
            data: [100,20,0]
        }
    ]
}

我想使用for循环获得结果。

4 个答案:

答案 0 :(得分:2)

您可以使用.reduce()并执行以下操作:



var arr = [
    {
        "Material": "113/133",
        "Name": [
            {
                "name": "WELD1",
                "value": 27520
            },
            {
                "name": "WELD2",
                "value": 676992
            },
            {
                "name": "WELD3",
                "value": 421
            }
        ]
    },
    {
        "Material": "150/300",
        "Name": [
            {
                "name": "WELD1",
                "value": 1441
            },
            {
                "name": "WELD2",
                "value": 555
            },
            {
                "name": "WELD3",
                "value": 100992
            }
        ]
    }
];

var newArr = arr.reduce((acc, ob) => {
  for (var key in ob)
     if(typeof acc[key] === 'object')
         acc[key] = acc[key] ? acc[key].concat(ob[key]) : [ob[key]];
     else
         acc[key] ? acc[key].push(ob[key]) : acc[key] = [ob[key]];
  return acc;
}, {}); 

console.log(newArr);




答案 1 :(得分:1)

let array = [
        {
            "Material": "113/133",
            "Name": [
                {
                    "name": "WELD1",
                    "value": 27520
                },
                {
                    "name": "WELD2",
                    "value": 676992
                },
                {
                    "name": "WELD3",
                    "value": 421
                }
            ]
        },
        {
            "Material": "150/300",
            "Name": [
                {
                    "name": "WELD1",
                    "value": 1441
                },
                {
                    "name": "WELD2",
                    "value": 555
                },
                {
                    "name": "WELD3",
                    "value": 100992
                }
            ]
        }
    ]

let answer = {Material: [], datasets: []}

array.forEach(x => {
  answer.Material.push(x.Material);
  
  x.Name.forEach(na => {
    let object = answer.datasets.find(obj => obj.label === na.name) || {label: "", data: []};
    
    if(object.label === ""){
    	object.label = na.name;
      object.data.push(na.value);
      answer.datasets.push(object);
    }else{
    	object.data.push(na.value)
    }
  });
  
  
});

console.log(answer);

以上是使用forEach代替reduce

的替代解决方案

答案 2 :(得分:0)

使用Array.reduce使用您拥有的数据构建新数据结构



const start = [{
    "Material": "113/133",
    "Name": [{
        "name": "WELD1",
        "value": 27520
      },
      {
        "name": "WELD2",
        "value": 676992
      },
      {
        "name": "WELD3",
        "value": 421
      }
    ]
  },
  {
    "Material": "150/300",
    "Name": [{
        "name": "WELD1",
        "value": 1441
      },
      {
        "name": "WELD2",
        "value": 555
      },
      {
        "name": "WELD3",
        "value": 100992
      }
    ]
  }
];

const end = start.reduce((tmp, {
  Material,
  Name,
}) => {
  // Handle the material
  // If it do not exist in the array, push it
  if (!tmp.Material.includes(Material)) {
    tmp.Material.push(Material);
  }

  // Handle the datasets
  // Look at each Name
  Name.forEach(({
    name,
    value,
  }) => {
    // Can we find the label?
    const labelFind = tmp.datasets.find(y => y.label === name);

    // If we can't find the label, create a new dataset
    if (!labelFind) {
      tmp.datasets.push({
        label: name,

        data: [
          value,
        ],
      });

      return;
    }

    // If we has found it push new value in the dataset 
    labelFind.data.push(value);
  });

  return tmp;
}, {
  Material: [],
  datasets: [],
});

console.log(end);




答案 3 :(得分:0)

// This is the old fashioned way.
// Iterate over whole array, 
// make a map, push value where 'name' is found in map
// later iterate over this map - dataMap - and form required datasets array.

var Material = [];
var dataMap = {};

arr.forEach(obj => {
    Material.push(obj.Material);
    obj.Name.forEach(item => {
        if(dataMap[item.name]){
            dataMap[item.name].push(item.value);
        }
        else {
            dataMap[item.name] = [item.value];
        }
    });
});

var datasets = [];
Object.keys(dataMap).forEach(label => {
    datasets.push({
        label: label,
        data: dataMap[label]
    });
});

var result = {
    Material: Material,
    datasets: datasets
}

console.log(result);