通过以特定顺序使用对象源数组中的属性进行分组来形成数组
Forming an array by grouping using the properties from source array of objects in a particular order
我有一组具有以下结构的对象作为响应发送:
let sampleData = [
{ values: { High: 4, Low: 5, Medium: 7 } , time: "1571372233234" , sum: 16 },
{ values: { High: 5, Low: 3, Medium : 1 }, time: "1571372233234" , sum: 9},
{ time: "14354545454", sum: 0},
{ time: "14354545454", sum: 0} }
];
我需要获取数组中每个对象中的每个键并从中形成一个数组。基本上根据所有 objects.If 中存在的键进行分组,对象没有 "values" 它应该 return 0 跨越 val1、val2、val3。
但是问题,问题中 "values" 对象中的键 "high,low,medium" 的顺序是不可预测的。使用我编写的任何代码,第一个对象中存在的键将被分组并遵循该顺序。但我想要它是任何输入命令,它应该总是给我这个命令 "High Medium Low" Order.
生成的对象数组应该看起来像并且应该始终遵循 "High Medium Order":
result = [
{ name: 'High', data: [4, 5, 0, 0] },
{ name: 'Medium', data: [5, 3, 0, 0] },
{ name: 'Low', data: [7, 1, 0, 0] }
]
我试过以下方法:
let sampleData = [{ values: { High: 4, Low: 5, Medium: 7 } , time: "1571372233234" , sum: 16 },{ values: { High: 5, Low: 3, Medium : 1 }, time: "1571372233234" , sum: 9},{ time: "14354545454", sum: 0},{ time: "14354545454", sum: 0 }];
const keySet = new Set(sampleData.flatMap(a => Object.keys(a.values || {})));
const merged = sampleData.reduce((acc, {
values = {}
}) => {
keySet.forEach(name => {
acc[name] = acc[name] || {
name,
data: []
};
acc[name].data.push(values[name] || 0);
});
return acc;
}, {});
console.log(merged);
您可以获取结果集并迭代键和数组的值。
let sampleData = [{ values: { High: 4, Low: 5, Medium: 7 }, time: "1571372233234", sum: 16 }, { values: { High: 5, Low: 3, Medium : 1 }, time: "1571372233234", sum: 9 }, { time: "14354545454", sum: 0 }, { time: "14354545454", sum: 0 }],
keys = ['High', 'Low', 'Medium'],
grouped = sampleData.reduce((r, { values = {} } = {}) => {
r.forEach(({ name, data }) => data.push(values[name] || 0));
return r;
}, keys.map(name => ({ name, data: [] })));
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
当属性 values
不存在时,您可以检查 undefined
值。
sampleData.reduce((a, {values: {High = 0, Low = 0, Medium = 0} = {}})
^
|
+-- When attr "values" is
undefined initialize
as an "empty" object.
let sampleData = [{ values: { High: 4, Low: 5, Medium: 7 } , time: "1571372233234" , sum: 16 },{ values: { High: 5, Low: 3, Medium : 1 }, time: "1571372233234" , sum: 9},{ time: "14354545454", sum: 0},{ time: "14354545454", sum: 0}];
let result = Object.values(sampleData.reduce((a, {values: {High = 0, Low = 0, Medium = 0} = {}}) => {
(a["High"] || (a["High"] = {name: "High", data: []})).data.push(High);
(a["Low"] || (a["Low"] = {name: "Low", data: []})).data.push(Low);
(a["Medium"] || (a["Medium"] = {name: "Medium", data: []})).data.push(Medium);
return a;
}, Object.create(null)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您正在返回一个对象,因此不能保证键的顺序。您可能需要一个数组而不是一个对象。
你可以像这样构造一个最终的 merged
对象
mergedFinal = [ merged['High'], merged['Medium'], merged['Low'] ]
我有一组具有以下结构的对象作为响应发送:
let sampleData = [
{ values: { High: 4, Low: 5, Medium: 7 } , time: "1571372233234" , sum: 16 },
{ values: { High: 5, Low: 3, Medium : 1 }, time: "1571372233234" , sum: 9},
{ time: "14354545454", sum: 0},
{ time: "14354545454", sum: 0} }
];
我需要获取数组中每个对象中的每个键并从中形成一个数组。基本上根据所有 objects.If 中存在的键进行分组,对象没有 "values" 它应该 return 0 跨越 val1、val2、val3。
但是问题,问题中 "values" 对象中的键 "high,low,medium" 的顺序是不可预测的。使用我编写的任何代码,第一个对象中存在的键将被分组并遵循该顺序。但我想要它是任何输入命令,它应该总是给我这个命令 "High Medium Low" Order.
生成的对象数组应该看起来像并且应该始终遵循 "High Medium Order":
result = [
{ name: 'High', data: [4, 5, 0, 0] },
{ name: 'Medium', data: [5, 3, 0, 0] },
{ name: 'Low', data: [7, 1, 0, 0] }
]
我试过以下方法:
let sampleData = [{ values: { High: 4, Low: 5, Medium: 7 } , time: "1571372233234" , sum: 16 },{ values: { High: 5, Low: 3, Medium : 1 }, time: "1571372233234" , sum: 9},{ time: "14354545454", sum: 0},{ time: "14354545454", sum: 0 }];
const keySet = new Set(sampleData.flatMap(a => Object.keys(a.values || {})));
const merged = sampleData.reduce((acc, {
values = {}
}) => {
keySet.forEach(name => {
acc[name] = acc[name] || {
name,
data: []
};
acc[name].data.push(values[name] || 0);
});
return acc;
}, {});
console.log(merged);
您可以获取结果集并迭代键和数组的值。
let sampleData = [{ values: { High: 4, Low: 5, Medium: 7 }, time: "1571372233234", sum: 16 }, { values: { High: 5, Low: 3, Medium : 1 }, time: "1571372233234", sum: 9 }, { time: "14354545454", sum: 0 }, { time: "14354545454", sum: 0 }],
keys = ['High', 'Low', 'Medium'],
grouped = sampleData.reduce((r, { values = {} } = {}) => {
r.forEach(({ name, data }) => data.push(values[name] || 0));
return r;
}, keys.map(name => ({ name, data: [] })));
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
当属性 values
不存在时,您可以检查 undefined
值。
sampleData.reduce((a, {values: {High = 0, Low = 0, Medium = 0} = {}})
^
|
+-- When attr "values" is
undefined initialize
as an "empty" object.
let sampleData = [{ values: { High: 4, Low: 5, Medium: 7 } , time: "1571372233234" , sum: 16 },{ values: { High: 5, Low: 3, Medium : 1 }, time: "1571372233234" , sum: 9},{ time: "14354545454", sum: 0},{ time: "14354545454", sum: 0}];
let result = Object.values(sampleData.reduce((a, {values: {High = 0, Low = 0, Medium = 0} = {}}) => {
(a["High"] || (a["High"] = {name: "High", data: []})).data.push(High);
(a["Low"] || (a["Low"] = {name: "Low", data: []})).data.push(Low);
(a["Medium"] || (a["Medium"] = {name: "Medium", data: []})).data.push(Medium);
return a;
}, Object.create(null)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您正在返回一个对象,因此不能保证键的顺序。您可能需要一个数组而不是一个对象。
你可以像这样构造一个最终的 merged
对象
mergedFinal = [ merged['High'], merged['Medium'], merged['Low'] ]