如何将对象的值转换为数组?
How do I turn the values from an object into an array?
我有一个轮询温度数据的函数:
{"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 映射函数,但我一直 运行 进入范围问题,其中 "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" 正在访问我的组件中的数据。
使用 Array#from, Object#entries, Array#map and destructuring 你可以做这样的事情。
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#reduce, Map、
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);
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.
您也许可以使用更简单的数据结构,例如。 { a: [43, 42, 43], b: [1, 2, 3] }
即。您可以使用 name
作为键,使用 data
数组作为值,而不是使用单独的 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"
).
可能有更优雅、更函数式的方法来做到这一点,但这可能会成功!
在我看来,您希望能够向数据对象添加多个数据集。一种方法是让数据对象具有知道如何向自身添加数据等操作的方法,可能如下所示。您可能希望将 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));
我有一个轮询温度数据的函数:
{"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 映射函数,但我一直 运行 进入范围问题,其中 "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" 正在访问我的组件中的数据。
使用 Array#from, Object#entries, Array#map and destructuring 你可以做这样的事情。
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#reduce, Map、
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);
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.
您也许可以使用更简单的数据结构,例如。 { a: [43, 42, 43], b: [1, 2, 3] }
即。您可以使用 name
作为键,使用 data
数组作为值,而不是使用单独的 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"
).
可能有更优雅、更函数式的方法来做到这一点,但这可能会成功!
在我看来,您希望能够向数据对象添加多个数据集。一种方法是让数据对象具有知道如何向自身添加数据等操作的方法,可能如下所示。您可能希望将 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));