如何将对象中的值转换为数组?

时间:2019-02-12 22:34:01

标签: javascript vue.js

我有一个轮询温度数据的函数:

{"a":"43",
"b":"43",
"c":"42",
"d":"43",
"e":"40",
"f":"41",
"g":"100",
"h":"42.6"}

我希望能够随时间绘制该数据图,但是我无法找出将上述数据映射到诸如以下数据之类的最佳方法:

temps: [{
    name: "a",
    data: ["43","42","43"]
  },
    name: "b",
    data: ["43","42","43"]
  },
    etc...
  ]

我尝试了下面的代码,并试图找出javascript map函数,但是我不断遇到范围界定问题,其中“ this”与父代中的东西不同:

this.temp_names.forEach(function(e){
    if(typeof this.temps[e] == "undefined") {
      this.temps[e] = []
    }
    this.temps.e.unshift(this.sys_telemetry.S.temps)
    if (this.temps.e.length > 10) {
      this.temps.e.pop()
    }
})

其中“ temp_names”是键的数组。

我正在VueJS中执行此操作,因此“ this”正在访问组件中的数据。

4 个答案:

答案 0 :(得分:2)

使用Array#fromObject#entriesArray#mapdestructuring,您可以执行以下操作。

const data={"a":"43","b":"43","c":"42","d":"43","e":"40","f":"41","g":"100","h":"42.6"}

const res = Object.entries(data)
.map(([name, data])=>({name, data:[data]}));

console.log(res);

替代使用Array#reduceMap

const data={"a":"43","b":"43","c":"42","d":"43","e":"40","f":"41","g":"100","h":"42.6"}

const res = Array.from(Object
.entries(data)
.reduce((a,[k,v])=>{
  if(!a.has(k)) a.set(k, []);
  a.get(k).push(v);
  return a;
}, new Map()))
.map(([name, data])=>({name, data}));

console.log(res);

答案 1 :(得分:1)

graph that data over time

由于您希望随着时间的推移执行此操作,因此创建一个数组,然后使用Object.entries和&Array.find更新结果是有意义的。

这里是一个例子。

const values1 = 
  {"a":"43", "b":"43", "c":"42", "d":"43", "e":"40", "f":"41",
  "g":"100", "h":"42.6"};
  
const values2 = 
  {"c":"44", "e":"39"};
  

const results =  [];

function addData(data) {
  Object.entries(data).forEach(([k, v]) => {
    let find = results.find(f => f.name === k);
    if (!find) {
      find = {
        name: k,
        data: []
      }
      results.push(find);
    }
    find.data.push(v);
  });
}

addData(values1); //data packet one arrives
addData(values2); //data packet two arrives
  
console.log(results); //results contains both data packet one & two.

答案 2 :(得分:0)

您也许可以摆脱一个简单的数据结构,例如。 { a: [43, 42, 43], b: [1, 2, 3] }

即。除了使用单独的namedata键之外,您还可以使用name作为键,并使用data数组作为值。

如果这可以代表每个键的时间轴,并且您的初始数据的结构类似于[{ a: 43, b: 1, c: 3 }, { a: 42, b: 2, c: 3 }],那么可能适合将后者转换为前者:

const output = {};

temp_data.forEach(x => {
  for (const key in x) {
    const y = x[key];

    if (typeof output[key] === 'undefined') {
      output[key] = [];
    }

    output[key].push(y);
  }
});

这将产生一个对象,其键与数据点中的键相匹配(例如“ a”,“ b”,“ c”等),并且其值是每个键的所有值的数组,这可能适合绘制时间线。

(顺便说一句,如果要在图形上将它们绘制为值,最好将这些值视为数字-例如1, 2, 3-而不是字符串-例如"1", "2", "3")。

可能有更优雅的,功能样式的方式来执行此操作,但这可能会完成工作!

答案 3 :(得分:0)

在我看来,您希望能够将多个数据集添加到数据对象。一种方法是使用一个数据对象,该对象具有知道如何执行操作的方法,例如向自己添加数据,也许类似以下内容。您可能想保留 index 属性的私有性,并可能对其进行排序,以使它始终按特定顺序排列,而与值的添加顺序无关。

var data0 = {"a":"43",
"b":"43",
"c":"42",
"d":"43"};

var data1 = {"a":"53",
"b":"53",
"c":"52",
"d":"53",
"e":"65"
};

class DataObject {

  constructor (data) {
    this.index = [];
    this.data = [];
    if (data) {
      this.addData(data);
    }
  }

  addData (data) {
    Object.keys(data).forEach(key => {
      let idx = this.index.indexOf(key);
      if (idx == -1) {
        idx = this.index.push(key) - 1;
        this.data.push({name:key, data:[]});
      }
      this.data[idx].data.push(data[key]);
    });
  }
}

// Initialise object with some data
let myData = new DataObject(data0);
console.log(JSON.stringify(myData.data));

// Add more data
myData.addData(data1);
console.log(JSON.stringify(myData.data));