Javascript基于多个级别创建平面格式的数组



我正在尝试创建一个堆叠条形图,如以下示例所示:http://jsfiddle.net/fct1p8j8/4/

当对数据进行硬编码时,它自己的图表工作得很好,那里一切都很好。

我正在努力弄清楚如何从我的数据库结构中获取正确格式的数据。

这是我的数据设置的示例输出:

[
{
"invDept": "Due Diligence",
"programs": {
"data": [
{
"program": "Brand Risk Management",
"total": "1847"
},
{
"program": "Due Diligence",
"total": "2718"
},
{
"program": "SAR",
"total": "17858"
}
]
}
},
{
"invDept": "Sanctions",
"programs": {
"data": [
{
"program": "Brand Risk Management",
"total": "500"
},
{
"program": "Due Diligence",
"total": "2100"
},
{
"program": "SAR",
"total": "16593"
}
]
}
}
]

x 轴将是来自对象的invDepartment值。 序列数据是我需要制作成图表必要格式的数据。

对于每个部门,我需要数组格式的每个程序的值。

例如,Brand Risk Management是程序名称,我需要Due Diligence部门和Sanctions部门的值。

我从做一个基本的循环开始,像这样创建数组结构:

获取我们的 X 轴部门

$.each(data.data, function (key, value) {
d = value;
xAxis.push(value.invDept);
// If an array for the department doesn't exist, create it now
if (typeof res[d.invDept] == "undefined" || !(res[d.invDept] instanceof Array)) {
res[d.invDept] = [];
}
});

从这里我有这样的东西:

res['Due Diligence'] = []

我被困在这一点上。不太确定我需要如何设置循环才能以平面格式获取此数据。

最终输出如下所示:

series: [{
name: 'Brand Risk Management',
data: [1847, 500]
}, {
name: 'Due Diligence',
data: [2718, 2100]
}, {
name: 'SAR',
data: [17858, 16593]
}]

使用Array.concat()Array.map()和 spread 语法将数据平展为单个数组。

然后将数组简化为一个 Map,该 Map 将具有相同键的对象合并到所需的结果中。完成后,将 Map 转换回带有Map.values()和扩展语法的数组。

const data = [{"invDept":"Due Diligence","programs":{"data":[{"program":"Brand Risk Management","total":"1847"},{"program":"Due Diligence","total":"2718"},{"program":"SAR","total":"17858"},{"program":"Sanctions - WLM","total":"885"}]}},{"invDept":"Sanctions","programs":{"data":[{"program":"Brand Risk Management","total":"500"},{"program":"Due Diligence","total":"2100"},{"program":"SAR","total":"16593"},{"program":"Sanctions - WLM","total":"443"}]}}]
const result = [... // spread the iterator to a new array
// flatten the array
[].concat(...data.map(({ programs }) => programs.data))
// reduce the data into a map
.reduce((r, { program: name, total }) => {
// if key doesn't exist create the object
r.has(name) || r.set(name, { name, data: [] }) 
// get the object, and add the total to the data array
r.get(name).data.push(total) 
return r;
}, new Map())
.values()] // get the Map's values iterator

console.log(result)

您可以使用函数reduce

var array = [  {    "invDept": "Due Diligence",    "programs": {      "data": [        {          "program": "Brand Risk Management",          "total": "1847"        },        {          "program": "Due Diligence",          "total": "2718"        },        {          "program": "SAR",          "total": "17858"        }      ]    }  },  {    "invDept": "Sanctions",    "programs": {      "data": [        {          "program": "Brand Risk Management",          "total": "500"        },        {          "program": "Due Diligence",          "total": "2100"        },        {          "program": "SAR",          "total": "16593"        }      ]    }  }],
result = { series: Object.values(array.reduce((a, c) => {
c.programs.data.forEach((d) => 
(a[d.program] || (a[d.program] = {data: [], name: d.program})).data.push(d.total));
return a;
}, {}))};
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

您可以使用array#reduce遍历数组并将值存储在对象累加器中。使用array#forEach迭代programsdata并填充对象累加器。然后使用Object.values()提取所有值

var data = [ { "invDept": "Due Diligence", "programs": { "data": [ { "program": "Brand Risk Management", "total": "1847" }, { "program": "Due Diligence", "total": "2718" }, { "program": "SAR", "total": "17858" }, { "program": "Sanctions - WLM", "total": "885" }] } }, { "invDept": "Sanctions", "programs": { "data": [ { "program": "Brand Risk Management", "total": "500" }, { "program": "Due Diligence", "total": "2100" }, { "program": "SAR", "total": "16593" }, { "program": "Sanctions - WLM", "total": "443" }] } } ],
result = Object.values(data.reduce((r,o) => {
o.programs.data.forEach(({program, total}) => {
r[program] = r[program] || {name: program, data: []};
r[program].data.push(total);
});
return r;
},{})),
output = {series: result};
console.log(output);
.as-console-wrapper{ max-height: 100% !important; top: 0;}

您可以使用reduce方法并将每个程序存储在新对象中作为其数组的键。我不知道你是否想要重复项,但如果不是,你只需将array object替换为set objectpush替换为add

let myPrograms = data.reduce((accumulator, item) => {
item && item.programs && item.programs.data && accumulateData(item.programs.data);
function accumulateData(program_data) {
for (let item of program_data) {
accumulator[item.program] ||
(accumulator[item.program] = [item.total],
accumulator[item.program].push(item.total));
}
}
return accumulator;
}, {});

您可以像这样访问myPrograms中的数据数组:

myPrograms["name of program"];

let data = [{
"invDept": "Due Diligence",
"programs": {
"data": [{
"program": "Brand Risk Management",
"total": "1847"
},
{
"program": "Due Diligence",
"total": "2718"
},
{
"program": "SAR",
"total": "17858"
},
{
"program": "Sanctions - WLM",
"total": "885"
}
]
}
},
{
"invDept": "Sanctions",
"programs": {
"data": [{
"program": "Brand Risk Management",
"total": "500"
},
{
"program": "Due Diligence",
"total": "2100"
},
{
"program": "SAR",
"total": "16593"
},
{
"program": "Sanctions - WLM",
"total": "443"
}
]
}
}
];
let myPrograms = data.reduce((accumulator, item) => {
item&&item.programs&&item.programs.data&& 
accumulateData(item.programs.data);
function accumulateData(program_data) {
for (let item of program_data) {
accumulator[item.program] || (accumulator[item.program] = [item.total], accumulator[item.program].push(item.total));
}
} 
return accumulator;
}, {});
console.log(myPrograms);
console.log(myPrograms["Brand Risk Management"]);

最新更新