遍历对象键和值并返回一个新对象

时间:2022-09-25 08:11:11

I've got an array of objects, which share common property names, but have different values. For example, they go like this:

我有一个对象数组,它们共享公共属性名,但值不同。例如,它们是这样的:

let data = [
    {
      value1: "11:00",
      value2: 0.737462,
      value3: 1.345341,
      value4: 0.684655
    },
    {
      value1: "12:00",
      value2: 0.894368,
      value3: 1.55891,
      value4: 0.784655
    },
    {
      value1: "13:00",
      value2: 1.140516,
      value3: 1.938695,
      value4: 0.454655
    }
]

From these objects, I need to form a new array of objects, similar to this:

从这些对象中,我需要形成一个新的对象数组,类似于:

let datasets = [
    {
        label: "value1",
        data: ["11:00", "12:00", "13:00"]
    },
    {
        label: "value2",
        data: [0.737462,0.894368,1.140516,]
    }
    // and so on
]

So that each object in my dataset would contain the original object's property name as a value for label and the array of properties that correspond to that name. I've tried to do it like this:

因此,我的数据集中的每个对象将包含原始对象的属性名作为标签的值,以及与该名称对应的属性数组。我试过这样做:

let datasets = data.map((n) => {
    for (i in n) {
        return {
            label: i,
            data: data.map(obj => obj[i])
        }
    }
});

But it doesn't work as expected -- it returns just an array of objects with only the first property name as a label throughout them all. I guess it's because it returns as soon as it gets to the first item in the for...in loop, but I can't figure out a better way to achieve what I need.

但它并不像预期的那样工作——它只返回一个对象数组,其中只有第一个属性名作为整个对象的标签。我想这是因为它一到第一项就会返回。在循环中,但是我想不出更好的方法来实现我所需要的。

3 个解决方案

#1


2  

The number of elements in the expected array is equal to the number of keys in an array element so map over that, then run another simple map to generate the data array.

预期数组中的元素数量等于数组元素中键的数量,因此映射到该数组元素,然后运行另一个简单的映射来生成数据数组。

var out = Object.keys(data[0]).map(function(key) {
  return {
    label: key,
    data: data.map(function(obj) {
      return obj[key];
    })
  };
}

#2


2  

You can do this with reduce() and ES6 Map.

可以使用reduce()和ES6映射来实现这一点。

let data = [{"value1":"11:00","value2":0.737462,"value3":1.345341,"value4":0.684655},{"value1":"12:00","value2":0.894368,"value3":1.55891,"value4":0.784655},{"value1":"13:00","value2":1.140516,"value3":1.938695,"value4":0.454655}]

var result = [...data.reduce(function(r, e) {
  return Object.keys(e).forEach(k => {
    if(!r.has(k)) r.set(k, {label: k, data: [e[k]]})
    else r.get(k).data.push(e[k])
  }), r
}, new Map).values()]

console.log(result)

#3


0  

const datasets = data.reduce((acc, a) => {
    return acc.map(set => Object.assign({}, set, { data: set.data.concat(a[set.label])}));
}, Object.keys(data[0]).map(k => ({label: k, data: []})));

Working fiddle here.

小提琴在这里工作。

#1


2  

The number of elements in the expected array is equal to the number of keys in an array element so map over that, then run another simple map to generate the data array.

预期数组中的元素数量等于数组元素中键的数量,因此映射到该数组元素,然后运行另一个简单的映射来生成数据数组。

var out = Object.keys(data[0]).map(function(key) {
  return {
    label: key,
    data: data.map(function(obj) {
      return obj[key];
    })
  };
}

#2


2  

You can do this with reduce() and ES6 Map.

可以使用reduce()和ES6映射来实现这一点。

let data = [{"value1":"11:00","value2":0.737462,"value3":1.345341,"value4":0.684655},{"value1":"12:00","value2":0.894368,"value3":1.55891,"value4":0.784655},{"value1":"13:00","value2":1.140516,"value3":1.938695,"value4":0.454655}]

var result = [...data.reduce(function(r, e) {
  return Object.keys(e).forEach(k => {
    if(!r.has(k)) r.set(k, {label: k, data: [e[k]]})
    else r.get(k).data.push(e[k])
  }), r
}, new Map).values()]

console.log(result)

#3


0  

const datasets = data.reduce((acc, a) => {
    return acc.map(set => Object.assign({}, set, { data: set.data.concat(a[set.label])}));
}, Object.keys(data[0]).map(k => ({label: k, data: []})));

Working fiddle here.

小提琴在这里工作。