Reputation: 6855
I am using chartjs chart in my angular application. And I have using a standart web api result for charts.
this.httpClient.get(this.REST_API_SERVER).subscribe((data: any[])=>{
console.log(data);
})
data is:
[
{ "label": "city-1", "data1": 200},
{ "label": "city-2", "data1": 450},
{ "label": "city-2", "data1": 950},
]
or
[
{ "label": "city-1", "data1": 200, "data2": 60 },
{ "label": "city-2", "data1": 450, "data2": 40 },
{ "label": "city-3", "data1": 950, "data2": 78 },
]
I mean, label
is label of chart and data1
, data2
or data3
is values of chart.
So I want to split this response data to two different array like following.
var labels = [ "city-1", "city-3", "city-3"];
var data = [
{ "data": [ 200, 450, 950 ], "label": "data1" },
{ "data": [ 60, 40, 78 ], "label": "data2" }
];
is this possible in angular rxjs mapping?
Upvotes: 2
Views: 495
Reputation: 6811
You can find here a working script:
const list = [
{ "label": "city-1", "data1": 200, "data2": 60 },
{ "label": "city-2", "data1": 450, "data2": 40 },
{ "label": "city-3", "data1": 950, "data2": 78 },
]
const result = list.reduce((acc, item) => {
const label = item['label'];
acc[0].push(label);
const keys = Object.keys(item).filter(key => key !== 'label');
keys.forEach(key => {
let labelItem = acc[1].find(value => value.label === key);
if (!labelItem) {
acc[1].push({ label:key, data: [item[key]] });
} else {
labelItem.data.push(item[key]);
}
});
return acc;
}, [[], []]);
console.log(result)
For typescript, you will need to add the type.
Upvotes: 1
Reputation: 6643
You can use reduce() to transform the data in required format.
Iterate on given data and if an item with current label exists, then append values to its data
array, if not create a new array item with current values.
let input = [
{ "label": "city-1", "data1": 200, "data2": 60 },
{ "label": "city-2", "data1": 450, "data2": 40 },
{ "label": "city-3", "data1": 950, "data2": 78 },
];
let result = input.reduce((acc, curr) => {
acc.labels = acc.labels || [];
acc.labels.push(curr.label);
acc.data = acc.data || [];
Object.entries(curr).forEach(([key, value]) => {
if (key !== "label") {
let item = acc.data.find(item => item.label === key);
if (item) {
item.data.push(value);
} else {
acc.data.push({
"data": [value],
"label": key
});
}
}
});
return acc;
}, {});
let labels = result.labels;
let data = result.data;
console.log("Labels", labels);
console.log("Data", data);
Upvotes: 2