修改
所以我想我应该再深入研究一下这个。我目前正在使用HighCharts JS。要在highcharts中显示数据,我必须得到如下最终数据:
[
{
name: 'Performing',
data: [1941404, 1028717, 697370, 0, 0, 0]
},
{
name: 'Non performing',
data: [0, 0, 0, 1759908, 890857, 280235]
},
{
name: 'Substandard',
data: [0, 0, 863825, 0, 0, 0]
},
{
name: 'Written-off',
data: [0, 0, 0, 0, 0, 77146]
}
]
'数据'是一个由6个对象组成的数组,用于填充图表的xAxis。
但是,我有以下通过MongoDb提供的数据
[
{
"_id": {
"data": "90 - 180",
"status": "Non Performing"
},
"value": 1759908
},
{
"_id": {
"data": "360",
"status": "Written-off"
},
"value": 77146
},
{
"_id": {
"data": "360",
"status": "Non Performing"
},
"value": 280235
},
{
"_id": {
"data": "30 - 90",
"status": "Substandard"
},
"value": 863825
},
{
"_id": {
"data": "30 - 90",
"status": "Performing"
},
"value": 697370
},
{
"_id": {
"data": "180 - 360",
"status": "Non Performing"
},
"value": 890857
},
{
"_id": {
"data": "0 - 30",
"status": "Performing"
},
"value": 1028717
},
{
"_id": {
"data": "0",
"status": "Performing"
},
"value": 1941404
}
]
我需要过滤后面的代码,以便它像以前的代码一样结束。非常重要的是,在数据数组中,我们最终得到6个对象,以确保我们填充整个xAxis的Highcharts,因此我们看到很多零,没有提供数据。
我真的希望这可以解决问题。感谢所有有帮助的人。我为因偏移而如此模糊而道歉。
快速注释 数据数组的顺序如下: 0,0-30,30-90,90-180,180-360,360
答案 0 :(得分:2)
使用.reduce
和.map
方法实现目标。
您可以使用.reduce
方法加入数据,以实现您想要的效果,然后使用.map
方法将其塑造回数组。
见下文:
const data = [
{
"_id": { "data": "90 - 180", "status": "Non Performing" }, "value": 1759908
},
{
"_id": { "data": "360", "status": "Written-off" }, "value": 77146
},
{
"_id": { "data": "360", "status": "Non Performing" }, "value": 280235
},
{
"_id": { "data": "30 - 90", "status": "Substandard" }, "value": 863825
},
{
"_id": { "data": "30 - 90", "status": "Performing" }, "value": 697370
},
{
"_id": { "data": "180 - 360", "status": "Non Performing" }, "value": 890857
},
{
"_id": { "data": "0 - 30", "status": "Performing" }, "value": 1028717
},
{
"_id": { "data": "0", "status": "Performing" }, "value": 1941404
}
]
const reducedMap = data.reduce((reducedMap, entry) => {
if(!reducedMap[entry._id.status]) reducedMap[entry._id.status] = [];
reducedMap[entry._id.status].push(entry.value);
return reducedMap;
}, {});
const reducedArray = Object.keys(reducedMap).map( key => ({
name: key,
data: reducedMap[key]
}))
修改强>
因此,在阅读了您的评论和其他答案之后,我想出了这个解决方案,它可以满足您的需求(请阅读其中的注释块以便了解):
// Define How the data is structured
const orderIdx = ["0", "0 - 30", "30 - 90", "90 - 180", "180 - 360", "360"];
const allStatuses = ["Performing", "Non Performing", "Substandard" , "Written-off"];
// Construct the mapping
const mappedIdx = orderIdx.reduce((m, key)=> { return { ...m, [key]: 0 } }, {})
// mappedIdx = { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 }
const mappedInput = allStatuses.reduce((m, name) => {
return {...m, [name]: Object.assign({},mappedIdx) };
}, {})
// mappedInput = {
// "Performing": { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 },
// "Non Performing": { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 },
// "Substandard" : { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 },
// "Written-off": { "0": 0, "0-30": 0, "30-90": 0, "90-180": 0, "180-360": 0, "360": 0 },
// }
// Loop on data
data.forEach( row => {
mappedInput[row._id.status][row._id.data] = row.value
})
const reducedArray = Object.keys(mappedInput).map( key => ({
name: key,
data: Object.keys(mappedInput[key]).map( dataKey => mappedInput[key][dataKey])
}))
// reducedArray = [
// {
// name: 'Performing',
// data: [1941404, 1028717, 697370, 0, 0, 0]
// },
// {
// name: 'Non performing',
// data: [0, 0, 0, 1759908, 890857, 280235]
// },
// {
// name: 'Substandard',
// data: [0, 0, 863825, 0, 0, 0]
// },
// {
// name: 'Written-off',
// data: [0, 0, 0, 0, 0, 77146]
// }
// ]
您也可以将其简化为一个简短的功能:
function summarizeData(data, orderIdx, allStatuses){
const mappedIdx = orderIdx.reduce((m, key)=> { return { ...m, [key]: 0 } }, {})
const mappedInput = allStatuses.reduce((m, name) => {
return {...m, [name]: Object.assign({},mappedIdx) };
}, {})
data.forEach( row => {
mappedInput[row._id.status][row._id.data] = row.value
})
return Object.keys(mappedInput).map( key => ({
name: key,
data: Object.keys(mappedInput[key]).map( dataKey => mappedInput[key][dataKey])
}))
}
summarizeData(data, ["0", "0 - 30", "30 - 90", "90 - 180", "180 - 360", "360"], ["Performing", "Non Performing", "Substandard" , "Written-off"])
请注意,您需要对orderIdx
和allStatuses
进行参数化,因为仅通过观察它们应该是什么来表达它并不十分清楚。此外,请确保放置一个验证这些实际上是唯一可以采用的值的过程。
答案 1 :(得分:0)
使用the reduce method,只需记住指定初始对象。
newData = yourData.reduce(function(element, accumulator){
if (accumulator already has element with name property equalling to element.status) {
// push value to existing array
} else {
// add new element
}
}, {}); // second argument is just an empty object
答案 2 :(得分:0)
通常,您希望您的代码尽可能简洁,同时仍然讲述它接受并返回的对象的故事。类似下面的内容将描述接受的未格式化对象,描述在其上执行的翻译并隐式描述函数返回的对象。
function generateFormattedArray(unformattedDataArray) {
const flattenedDataArray = unformattedDataArray.forEach((obj) => { status: obj['_id'].status, value: obj.value });
return [
{
name: 'Performing',
data: flattenedDataArray.filter((obj) => obj.status === 'Performing').forEach((obj) => obj.value),
},
{
name: 'Non performing',
data: flattenedDataArray.filter((obj) => obj.status === 'Non performing').forEach((obj) => obj.value),
},
{
name: 'Substandard',
data: flattenedDataArray.filter((obj) => obj.status === 'Substandard').forEach((obj) => obj.value),
},
{
name: 'Written-off',
data: flattenedDataArray.filter((obj) => obj.status === 'Written-off').forEach((obj) => obj.value),
},
];
}
虽然说实话,除非这个嵌套格式有特定的用例......我宁愿使用在第2行创建的flattenedDataArray。
答案 3 :(得分:-1)
你可以这样做:
var originalArray = [
{
"_id": {
"data": "90 - 180",
"status": "Non Performing"
},
"value": 1759908
},
{
"_id": {
"data": "360",
"status": "Written-off"
},
"value": 77146
},
{
"_id": {
"data": "360",
"status": "Non Performing"
},
"value": 280235
},
{
"_id": {
"data": "30 - 90",
"status": "Substandard"
},
"value": 863825
},
{
"_id": {
"data": "30 - 90",
"status": "Performing"
},
"value": 697370
},
{
"_id": {
"data": "180 - 360",
"status": "Non Performing"
},
"value": 890857
},
{
"_id": {
"data": "0 - 30",
"status": "Performing"
},
"value": 1028717
},
{
"_id": {
"data": "0",
"status": "Performing"
},
"value": 1941404
}
];
var newArray = [
{
'name': 'Performing',
'data': []
},
{
'name': 'Non Performing',
'data': []
},
{
'name': 'Substandard',
'data': []
},
{
'name': 'Written-off',
'data': []
}
];
for (var x = 0; x < originalArray.length; x++) {
if (originalArray[x]._id.status === 'Performing') {
for (var y = 0; y < newArray.length; y++) {
if (newArray[y].name === 'Performing') {
newArray[y].data.push(originalArray[x]._id.data)
}
}
} else if (originalArray[x]._id.status === 'Non Performing') {
for (var y = 0; y < newArray.length; y++) {
if (newArray[y].name === 'Non Performing') {
newArray[y].data.push(originalArray[x]._id.data)
}
}
} else if (originalArray[x]._id.status === 'Substandard') {
for (var y = 0; y < newArray.length; y++) {
if (newArray[y].name === 'Substandard') {
newArray[y].data.push(originalArray[x]._id.data)
}
}
} else if (originalArray[x]._id.status === 'Written-off') {
for (var y = 0; y < newArray.length; y++) {
if (newArray[y].name === 'Written-off') {
newArray[y].data.push(originalArray[x]._id.data)
}
}
}
}
console.log(newArray);