我正在使用js,并从响应中获得一个动态对象数组,如下所示:
[
{fromCountry: "TE", toCountry: "FE", type: "new", status: "created"},
{fromCountry: "TE", toCountry: "FE", type: "old", status: "cold"},
{fromCountry: "CD", toCountry: "EG", type: "used", status: "hot"},
{fromCountry: "CD", toCountry: "EG", type: "old", status: "hot"},
{fromCountry: "CD", toCountry: "EG", type: "old", status: "cold"}
];
我想创建一个新数组,因此我想按fromCountry对它们进行分组,计算fromCountry并添加具有类型和值的嵌套数组。它应该看起来像是:
[
{ name: "TE", value: 2, child: [{ name: "new", value: 1 }, { name: "old", value: 1 }]},
{ name: "CD", value: 3, child: [{ name: "used", value: 1}, { name: "old", value: 2 }]}
]
(注意:我不想使用额外的JavaScript库)
能帮我吗?
答案 0 :(得分:1)
您可以使用reduce
将数组分组为一个对象。使用Object.values
将对象转换为数组。
var arr = [{fromCountry:"TE",toCountry:"FE",type:"new",status:"created"},{fromCountry:"TE",toCountry:"FE",type:"old",status:"cold"},{fromCountry:"CD",toCountry:"EG",type:"used",status:"hot"},{fromCountry:"CD",toCountry:"EG",type:"old",status:"hot"},{fromCountry:"CD",toCountry:"EG",type:"old",status:"cold"}];
var result = Object.values(arr.reduce((c, {fromCountry,type}) => {
c[fromCountry] = c[fromCountry] || {name: fromCountry,value: 0,child: {}};
c[fromCountry].child[type] = c[fromCountry].child[type] || {name: type,value: 0};
c[fromCountry].child[type].value++;
c[fromCountry].value++;
return c;
}, {})).map(o => {
o.child = Object.values(o.child);
return o;
});
console.log(result);
答案 1 :(得分:1)
这是一种较慢的旧方法,它制作临时对象并根据所看到的内容递增值。
我敢肯定有一种更快的方法可以做到,所以请密切注意其他答案。
我已经注释了代码,但是随时可以问是否有什么不合理的地方。
var objs = [{fromCountry:"TE",toCountry:"FE",type:"new",status:"created"},{fromCountry:"TE",toCountry:"FE",type:"old",status:"cold"},{fromCountry:"CD",toCountry:"EG",type:"used",status:"hot"},{fromCountry:"CD",toCountry:"EG",type:"old",status:"hot"},{fromCountry:"CD",toCountry:"EG",type:"old",status:"cold"}];
// temp object and output array
let holding = {};
let output = [];
// for each object
for (let obj of objs) {
// if it's the first time we've seen this fromCountry make it
// and give it a value of 0
if (!holding[obj.fromCountry]) holding[obj.fromCountry] = {
value: 0
};
// if it's the first time we've seen this type make it and
// give it a value of 0
if (!holding[obj.fromCountry][obj.type]) holding[obj.fromCountry][obj.type] = {
value: 0
};
// increment values
holding[obj.fromCountry].value++;
holding[obj.fromCountry][obj.type].value++
}
// Now we need to reformat the object
// for each key in the holding object
for (let key of Object.keys(holding)) {
// make a new temp object in the right format
let temp = {
name: key,
value: holding[key].value,
child: []
};
// for each inner key in the holding object
for (let innerKey of Object.keys(holding[key])) {
// skip over value
if (innerKey == "value") continue
// make another temp object to be pushed to child
let innertemp = {
name: innerKey,
value: holding[key][innerKey].value
}
// push inner temp object to child
temp.child.push(innertemp);
}
//push whole temp object, now formatted correctly, to the output array
output.push(temp);
}
console.log(output);
我希望这对您有帮助
答案 2 :(得分:1)
let arr = [
{fromCountry:"TE",toCountry:"FE",type:"new",status:"created"},
{fromCountry:"TE",toCountry:"FE",type:"old",status:"cold"},
{fromCountry:"CD",toCountry:"EG",type:"used",status:"hot"},
{fromCountry:"CD",toCountry:"EG",type:"old",status:"hot"},
{fromCountry:"CD",toCountry:"EG",type:"old",status:"cold"}
];
let answer = [];
arr.forEach(x=> {
if(!answer.some(y => y.name === x.fromCountry)){
let newAnswer = {};
newAnswer.name = x.fromCountry;
newAnswer.value = 1;
newAnswer.child = [];
let child = {name: x.type, value: 1};
newAnswer.child.push(child);
answer.push(newAnswer);
}else{
let existAnswer = answer.find(y=>y.name === x.fromCountry);
existAnswer.value++;
if(existAnswer.child.some(z=>z.name === x.type)){
let childObj = existAnswer.child.find(z=>z.name === x.type);
childObj.value++;
}else{
let newChildObj = {name: x.type, value: 1}
existAnswer.child.push(newChildObj);
}
}
})
console.log(answer)
我们遍历整个数组,找到element的存在,如果发现则不加提示,如果找不到,则推送一个新对象。同样的逻辑也适用于子对象Obj 这可能不是一种优雅的方法,但我相信它更容易理解。您是非常主观的。
答案 3 :(得分:1)
您可以将函数用于任意数量的组。
此提议的特征是一个对象,该对象将单个对象保留为部分结果,分组结果和哈希(给定键的值),并将其作为组的访问器。
下划线属性_
对于将播放负载对象与对象的哈希函数分开是必需的。
动态创建可能需要的子数组。
结果是一个嵌套结构,其深度与给定的groups数组相同。
function getGouped(array, groups) {
var result = [],
object = { _: { children: result } };
array.forEach(function (a) {
groups.reduce(function (r, k) {
var name = a[k];
if (!r[name]) {
r[name] = { _: { name, count: 0 } };
r._.children = r._.children || [];
r._.children.push(r[name]._);
}
r[name]._.count++;
return r[name];
}, object);
});
return result;
}
var data = [{ fromCountry: "TE", toCountry: "FE", type: "new", status: "created" }, { fromCountry: "TE", toCountry: "FE", type: "old", status: "cold" }, { fromCountry: "CD", toCountry: "EG", type: "used", status: "hot" }, { fromCountry: "CD", toCountry: "EG", type: "old", status: "hot" }, { fromCountry: "CD", toCountry: "EG", type: "old", status: "cold" }];
console.log(getGouped(data, ['fromCountry', 'type']));
console.log(getGouped(data, ['fromCountry', 'type', 'status']));
.as-console-wrapper { max-height: 100% !important; top: 0; }