Reorder an array from a specific data - javascript

I have absolutely no idea of which title I could write.
Actually, here is what I get from API :
[
{
"order": 1,
"role": {
"label": "singer"
},
"artist": {
"name": "AaRON"
}
},
{
"order": 1,
"role": {
"label": "author"
},
"artist": {
"name": "Simon Buret"
}
},
{
"order": 2,
"role": {
"label": "author"
},
"artist": {
"name": "Olivier Coursier"
}
},
{
"order": 1,
"role": {
"label": "composer"
},
"artist": {
"name": "John Doe"
}
}
]
And here is what I need to send :
"artist": {
"singer": [
"AaRON"
],
"author": [
"Simon Buret",
"Olivier Coursier"
]
}
Of course, the order property must be taken in account.
Example : Simon Buret is the first item because he has the order set to 1.
I have absolutely no idea how to implement that, I just did a map, but don't know what to put inside :/
this.artistControl.controls.map(artistControl => {
...
});
Is there a way to do what I need ?

Does this work for you:
let arr = [
{ "order": 1, "role": { "label": "singer" }, "artist": { "name": "AaRON" } },
{ "order": 1, "role": { "label": "author" }, "artist": { "name": "Simon Buret" } },
{ "order": 2, "role": { "label": "author" }, "artist": { "name": "Olivier Coursier" } },
{ "order": 1, "role": { "label": "composer" }, "artist": { "name": "John Doe" } }
];
let obj = {'artist': {}};
arr.forEach(a => {
obj['artist'][a.role.label] = obj['artist'][a.role.label] || [];
obj['artist'][a.role.label][a.order-1] = a.artist.name;
});
console.log(obj);

You could use reduce method with object as a accumulator param and then check if the key doesn't exist create it with empty array as value and then add names by order.
const data = [{"order":1,"role":{"label":"singer"},"artist":{"name":"AaRON"}},{"order":1,"role":{"label":"author"},"artist":{"name":"Simon Buret"}},{"order":2,"role":{"label":"author"},"artist":{"name":"Olivier Coursier"}},{"order":1,"role":{"label":"composer"},"artist":{"name":"John Doe"}}]
const result = data.reduce((r, {
role: { label },
artist: { name },
order
}) => {
if (name) {
if (!r[label]) r[label] = [];
r[label][order - 1] = name;
}
return r;
}, {})
console.log(result)

const array = [{"order":1,"role":{"label":"singer"},"artist":{"name":"AaRON"}},{"order":1,"role":{"label":"author"},"artist":{"name":"Simon Buret"}},{"order":2,"role":{"label":"author"},"artist":{"name":"Olivier Coursier"}},{"order":1,"role":{"label":"composer"},"artist":{"name":"John Doe"}}];
const result = array
.sort((item1, item2) => item1.order - item2.order)
.reduce((acc, { role, artist }) => ({
...acc,
artist: {
...acc.artist,
[role.label]: [
...(acc.artist[role.label] || []),
artist.name,
],
},
}), { artist: {} });
console.log(result);

Here is another approach with es5
const data = [{ "order": 1, "role": { "label": "singer" }, "artist": { "name": "AaRON" } }, { "order": 1, "role": { "label": "author" }, "artist": { "name": "Simon Buret" } }, { "order": 2, "role": { "label": "author" }, "artist": { "name": "Olivier Coursier" } }, { "order": 1, "role": { "label": "composer" }, "artist": { "name": "John Doe" } }];
var result = data.reduce(function(map, obj) {
map["artist"] = map["artist"] || {};
if (obj.role.label === 'author' || obj.role.label === 'singer') {
map["artist"][obj.role.label] = map["artist"][obj.role.label] || [];
map["artist"][obj.role.label][obj.order - 1] = obj.artist.name;
}
return map;
}, {});
console.log(result)

Related

How to combine multiple JSON object that have same key and value

How to combine JSON objects in the same response that has the same key and value with javascript? This is my data for example:
{
"data": [
{
"name": "A",
"description": {
"location": "location1",
"floor": "floor1",
},
},
{
"name": "A",
"description": {
"location": "location2",
"floor": "floor1",
},
},
{
"name": "B",
"description": {
"location": "location3",
"floor": "floor3",
},
},
]
}
And turn it into this:
{
"data": [
{
"name": "A",
"description": {
"location": ["location1","location2"],
"floor": "floor1",
},
},
{
"name": "B",
"description": {
"location": "location3",
"floor": "floor3",
},
},
]
}
Basically I am someone who is new to learning javascript. Any help would be very helpful, thank you.
You can do:
const data = {data: [{name: 'A',description: {location: 'location1',floor: 'floor1',},},{name: 'A',description: {location: 'location2',floor: 'floor1',},},{name: 'B',description: {location: 'location3',floor: 'floor3',},},],}
const result = {
data: data.data.reduce((a, { name, description }) => {
const index = a.findIndex((d) => d.name === name)
if (index >= 0) {
let location = a[index].description.location
location = Array.isArray(location) ? location : [location]
a[index].description.location = [...location, description.location]
} else {
a.push({ name, description })
}
return a
}, []),
}
console.log(result)
const list = {
"data": [
{
"name": "A",
"description": {
"location": "location1",
"floor": "floor1",
},
},
{
"name": "A",
"description": {
"location": "location2",
"floor": "floor1",
},
},
{
"name": "B",
"description": {
"location": "location3",
"floor": "floor3",
},
},
]
};
const consolidatedData = [];
for (const ele of list.data) {
const isExist = consolidatedData.find(x => x.name === ele.name);
if (!isExist) {
consolidatedData.push({
...ele
})
} else {
const objectKey = consolidatedData.findIndex(x => x.name === ele.name);
if (objectKey > -1) {
const description = consolidatedData[objectKey].description;
const newDes = ele.description;
if (newDes.location !== description.location) {
const data = consolidatedData[objectKey].description;
const added = [data.location, ele.description.location];
delete consolidatedData[objectKey].description.location
consolidatedData[objectKey].description["location"] = added
}
if (newDes.floor !== description.floor){
const data = consolidatedData[objectKey].floor;
const added = [data.floor, ele.description.floor];
delete consolidatedData[objectKey].description.floor
consolidatedData[objectKey].description["floor"] = added
}
}
}
}
console.log(JSON.stringify(consolidatedData, null, 2));
Here is a solution that uses an intermediate bucket object. The desired result object is then constructed from the bucket object:
const input = { "data": [ { "name": "A", "description": { "location": "location1", "floor": "floor1", }, }, { "name": "A", "description": { "location": "location2", "floor": "floor1", }, }, { "name": "B", "description": { "location": "location3", "floor": "floor3", }, }, ] };
let buckets = input.data.reduce((acc, obj) => {
if(!acc[obj.name]) {
acc[obj.name] = {
locations: {},
floors: {}
};
}
acc[obj.name].locations[obj.description.location] = true;
acc[obj.name].floors[obj.description.floor] = true;
return acc;
}, {});
console.log('buckets: ', buckets);
let result = {
data: Object.keys(buckets).map(name => {
let locations = Object.keys(buckets[name].locations);
let floors = Object.keys(buckets[name].floors);
return {
name: name,
description: {
location: locations.length == 1 ? locations[0] : locations,
floor: floors.length == 1 ? floors[0] : floors
}
}
})
};
console.log('result:', result);
Notes:
buckets object:
is created using an array .reduce()
array .reduce() docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
locations and floors are collected using objects instead of arrays, this is to avoid duplicate names
result object:
is using Object.keys(buckets) to get the array of names
.map() transforms each name into the desired object
your unusual array or string value for location and floor is constructed with a conditional

How do return the value of an attribute in a nested object without using the traditional js object navigation style?

For example how do I automatically loop through all "value" attributes in the object below without doing "tags.value" or "style.value"
[
{
"title": "Old Man's War",
"author": {
"name": "John Scalzi",
"tags": [
{
"value": "American"
}
]
}
},
{
"title": "The Lock Artist",
"author": {
"name": "Steve Hamilton",
"tags": [
{
"value": "English"
}
"style": [
{
"value": "Italix"
}
]
}
}
]
Were you looking to extract a list of all styles & tags? One direct way is through a reduce(), map() combo
let attributes = data.reduce((b, a) => ({
tags: [...b.tags, a.author.tags?.map(v => v.value) || []].flat(),
styles: [...b.styles, a.author.style?.map(v => v.value) || []].flat() }), {tags:[], styles:[]})
Output:
{
"tags": [
"American",
"English"
],
"styles": [
"Italix"
]
}
const data = [{
"title": "Old Man's War",
"author": {
"name": "John Scalzi",
"tags": [{
"value": "American"
}]
}
}, {
"title": "The Lock Artist",
"author": {
"name": "Steve Hamilton",
"tags": [{
"value": "English"
}],
"style": [{
"value": "Italix"
}]
}
}]
// just the tag values
let attributes = data.reduce((b, a) => ({
tags: [...b.tags, a.author.tags?.map(v => v.value) || []].flat(),
styles: [...b.styles, a.author.style?.map(v => v.value) || []].flat() }), {tags:[], styles:[]})
console.log(attributes)
//first,there is an error in your json.I assume it like this
const data = [
{
"title":"Old Man's War",
"author":{
"name":"John Scalzi",
"tags":[
{
"value":"American"
}
]
}
},
{
"title":"The Lock Artist",
"author":{
"name":"Steve Hamilton",
"tags":[
{
"value":"English"
}
],
"style":[
{
"value":"Italix"
}
]
}
}
]
for(const top of data){
if(typeof top == 'object'){
for(const second_key in top){
const second = top[second_key]
if(typeof second == 'object'){
for(const third_key in second){
const third = second[third_key]
if(Array.isArray(third)){
for(const fourth of third){
document.write(fourth['value']+"<br>")
}
}
}
}
}
}
}
//this is another solution
const data = [
{
"title":"Old Man's War",
"author":{
"name":"John Scalzi",
"tags":[
{
"value":"American"
}
]
}
},
{
"title":"The Lock Artist",
"author":{
"name":"Steve Hamilton",
"tags":[
{
"value":"English"
}
],
"style":[
{
"value":"Italix"
}
]
}
}
]
function lookForValue(obj){
if(obj.hasOwnProperty('value')){
document.write(obj['value']+"<br>")
return
}
if(typeof obj == 'object'){
for(const key in obj){
lookForValue(obj[key])
}
}
if(Array.isArray(obj)){
for(const item in obj){
lookForValue(item)
}
}
}
lookForValue(data)

Iterate and group the objects using map function

Check for the decimal id and group them accordingly.
Below are the sample and recommended JSON's
Sample JSON
{
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
}
Would like to iterate and Re-structure the above JSON into below recommended format.
Logic: Should check the id(with and without decimals) and group them based on the number.
For Example:
1, 1.1, 1.2.3, 1.4.5 => data1: [{id: 1},{id: 1.1}....]
2, 2.3, 2.3.4 => data2: [{id: 2},{id: 2.3}....]
3, 3.1 => data3: [{id: 3},{id: 3.1}]
Recommended JSON
{
"results": [
{
"data1": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
}
]
},
{
"data2": [
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
}
]
},
{
"data3": [
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
}
]
},
{
"data4": [
{
"name": "Download",
"id": "4.2"
}
]
}
]
}
I have tried the below solution but it doesn't group the object
var formatedJSON = [];
results.map(function(d,i) {
formatedJSON.push({
[data+i]: d
})
});
Thanks in advance.
You can use reduce like this. The idea is to create a key-value pair for each data1, data2 etc so that values in this object are the values you need in the final array. Then use Object.values to get those as an array.
const sampleJson = {"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]}
const grouped = sampleJson.results.reduce((a, v) => {
const key = `data${parseInt(v.id)}`;
(a[key] = a[key] || {[key]: []})[key].push(v);
return a;
},{});
console.log({results: Object.values(grouped)})
One liner / Code-golf:
let s={"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]},k;
console.log({results:Object.values(s.results.reduce((a,v)=>(k=`data${parseInt(v.id)}`,(a[k] = a[k]||{[k]:[]})[k].push(v),a),{}))})
Here you go:
var data = {
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
};
let newSet = new Set();
data.results.forEach(e => {
let key = e.id.substring(0, e.id.indexOf('.'));
console.log(key);
if (newSet.has(key) == false) {
newSet.add(key);
newSet[key] = [];
}
newSet[key].push(e.id);
});
console.log(newSet);
Here's how you'd do it:
var data = {
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
};
var newData = {
"results": {}
};
data.results.forEach(item => {
var num = item.id.slice(0, 1);
if (newData.results["data" + num]) {
newData.results["data" + num].push(item);
} else {
newData.results["data" + num] = [item];
}
})
data = newData;
console.log(data);
What this does is it iterates through each item in results, gets the number at the front of this item's id, and checks if an array of the name data-{num} exists. If the array exists, it's pushed. If it doesn't exist, it's created with the item.
let input = getInput();
let output = input.reduce((acc, curr)=>{
let {id} = curr;
let majorVersion = 'name' + id.split('.')[0];
if(!acc[majorVersion]) acc[majorVersion]= [];
acc[majorVersion].push(curr);
return acc;
},{})
console.log(output)
function getInput(){
return [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
}
One solution with RegEx for finer control as it would differentiate easily between 1 and 11.
Also this will make sure that even if the same version comes in end(say 1.9 in end) it will put it back in data1.
let newArr2 = ({ results }) =>
results.reduce((acc, item) => {
let key = "data" + /^(\d+)\.?.*/.exec(item.id)[1];
let found = acc.find(i => key in i);
found ? found[key].push(item) : acc.push({ [key]: [item] });
return acc;
}, []);

JSON - search array for value based on unique ID

I have the following JSON Feed:
var data = {
"feeds": {
"regions": [
{
"name": "Lichtenberg",
"id": "01408.b",
"suburbs": [
{ "name": "Fennpfuhl", "views": 76400 },
{ "name": "Lichtenberg", "views": 87895 },
{ "name": "Rummelsberg", "views": 10239 }
]
},
{
"name": "Mitte",
"id": "03442.f",
"suburbs": [
{ "name": "Tiergarten", "views": 82695 },
{ "name": "Mitte", "views": 67234 },
{ "name": "Hansaviertel", "views": 10848 },
{ "name": "Moabit", "views": 67500 }
]
},
{
"name": "Friedrichshain-Kreuzberg",
"id": "01991.o",
"suburbs": [
{ "name": "Friedrichshain", "views": "98494" },
{ "name": "Kreuzberg", "views": "27800" }
]
},
{
"name": "Templehof-Schöneberg",
"id": "01778.k",
"suburbs": [
{ "name": "Friedenau", "views": 76595 },
{ "name": "Schöneberg", "views": 20731 },
{ "name": "Templehof", "views": 58000 },
{ "name": "Mariendorf", "views": 32300 }
]
},
{
"name": "Pankow",
"id": "02761.q",
"suburbs": [
{ "name": "Wießensee", "views": 81294 },
{ "name": "Prenzlauer Berg", "views": 76470 },
{ "name": "Pankow", "views": 90210 }
]
}
],
"branding": [
{
"municipality_id": "01408.b",
"brand_color": "#f9cd90"
},{
"municipality_id": "03442.f",
"brand_color": "#F28123"
},{
"municipality_id": "01991.o",
"brand_color": "#D34E24"
},{
"municipality_id": "01778.k",
"brand_color": "#563F1B"
},{
"municipality_id": "02761.q",
"brand_color": "#38726C"
}
],
"customer": {
"name": "Viktoria Tiedemann",
"date_of_birth": "1981-09-19",
"address": {
"street": "Schönfließer Str 9",
"suburb": "Prenzlauer Berg",
"postcode": "10439"
}
}
}
};
In essence what I want to do is to create an array that contains 3 items:
Name of the region data.feeds.regions.name
Total views of the region
Color of the chart based on the data.feeds.regions.id that is then used as a lookup key to data.branding to get the brand_color of that region.
I've got the answer for parts 1 and 2 from a previous SO Question:
var viewsPerRegion = data.feeds.regions.map(({ name, suburbs }) => ({
label: name,
total: suburbs.reduce((a, { views }) => a + Number(views), 0)
}));
My attempt at getting the third one so far is as follows:
var viewsPerRegionStyled = data.feeds.regions.map(({ name, id, suburbs }) => ({
label: name,
total: suburbs.reduce((a, { views }) => a + Number(views), 0),
color: if (data.feeds.region.id == data.branding.municipality_id)
{
data.branding.brand_color}
}));
I'm sure I'm completely lost on this one - any help is truly appreciated.
You need to call find on the branding array to find the element with the matching municipality_id and then extract the found brand_color property:
var data={"feeds":{"regions":[{"name":"Lichtenberg","id":"01408.b","suburbs":[{"name":"Fennpfuhl","views":76400},{"name":"Lichtenberg","views":87895},{"name":"Rummelsberg","views":10239}]},{"name":"Mitte","id":"03442.f","suburbs":[{"name":"Tiergarten","views":82695},{"name":"Mitte","views":67234},{"name":"Hansaviertel","views":10848},{"name":"Moabit","views":67500}]},{"name":"Friedrichshain-Kreuzberg","id":"01991.o","suburbs":[{"name":"Friedrichshain","views":"98494"},{"name":"Kreuzberg","views":"27800"}]},{"name":"Templehof-Schöneberg","id":"01778.k","suburbs":[{"name":"Friedenau","views":76595},{"name":"Schöneberg","views":20731},{"name":"Templehof","views":58000},{"name":"Mariendorf","views":32300}]},{"name":"Pankow","id":"02761.q","suburbs":[{"name":"Wießensee","views":81294},{"name":"Prenzlauer Berg","views":76470},{"name":"Pankow","views":90210}]}],"branding":[{"municipality_id":"01408.b","brand_color":"#f9cd90"},{"municipality_id":"03442.f","brand_color":"#F28123"},{"municipality_id":"01991.o","brand_color":"#D34E24"},{"municipality_id":"01778.k","brand_color":"#563F1B"},{"municipality_id":"02761.q","brand_color":"#38726C"}],"customer":{"name":"Viktoria Tiedemann","date_of_birth":"1981-09-19","address":{"street":"Schönfließer Str 9","suburb":"Prenzlauer Berg","postcode":"10439"}}}}
var viewsPerRegionStyled = data.feeds.regions.map(({ name, id, suburbs }) => ({
label: name,
total: suburbs.reduce((a, { views }) => a + Number(views), 0),
color: data.feeds.branding.find(
({ municipality_id }) => municipality_id === id
).brand_color
}));
console.log(viewsPerRegionStyled);
Another option is to transform the branding array into an object indexed by municipality_id beforehand, which will allow for simple object lookup, which has less complexity than .find:
var data={"feeds":{"regions":[{"name":"Lichtenberg","id":"01408.b","suburbs":[{"name":"Fennpfuhl","views":76400},{"name":"Lichtenberg","views":87895},{"name":"Rummelsberg","views":10239}]},{"name":"Mitte","id":"03442.f","suburbs":[{"name":"Tiergarten","views":82695},{"name":"Mitte","views":67234},{"name":"Hansaviertel","views":10848},{"name":"Moabit","views":67500}]},{"name":"Friedrichshain-Kreuzberg","id":"01991.o","suburbs":[{"name":"Friedrichshain","views":"98494"},{"name":"Kreuzberg","views":"27800"}]},{"name":"Templehof-Schöneberg","id":"01778.k","suburbs":[{"name":"Friedenau","views":76595},{"name":"Schöneberg","views":20731},{"name":"Templehof","views":58000},{"name":"Mariendorf","views":32300}]},{"name":"Pankow","id":"02761.q","suburbs":[{"name":"Wießensee","views":81294},{"name":"Prenzlauer Berg","views":76470},{"name":"Pankow","views":90210}]}],"branding":[{"municipality_id":"01408.b","brand_color":"#f9cd90"},{"municipality_id":"03442.f","brand_color":"#F28123"},{"municipality_id":"01991.o","brand_color":"#D34E24"},{"municipality_id":"01778.k","brand_color":"#563F1B"},{"municipality_id":"02761.q","brand_color":"#38726C"}],"customer":{"name":"Viktoria Tiedemann","date_of_birth":"1981-09-19","address":{"street":"Schönfließer Str 9","suburb":"Prenzlauer Berg","postcode":"10439"}}}}
var colorsById = data.feeds.branding.reduce((a, { municipality_id, brand_color }) => {
a[municipality_id] = brand_color;
return a;
}, {});
var viewsPerRegionStyled = data.feeds.regions.map(({ name, id, suburbs }) => ({
label: name,
total: suburbs.reduce((a, { views }) => a + Number(views), 0),
color: colorsById[id]
}));
console.log(viewsPerRegionStyled);

node js create an object in specific pattern from array of object

I'm facing some issue in for loop while creating an object from array of object.I have an array as this in node js app:
[
{
"Material": "113/133",
"Name": [
{
"name": "WELD1",
"value": 27520
},
{
"name": "WELD2",
"value": 676992
},
{
"name": "WELD3",
"value": 421
}
]
},
{
"Material": "150/300",
"Name": [
{
"name": "WELD1",
"value": 1441
},
{
"name": "WELD2",
"value": 555
},
{
"name": "WELD3",
"value": 100992
}
]
}
]
I want to return object like this which contains all the Material as array, Name and there value in array of object like this:
{
Material: ["113/133", "150/300"],
datasets: [
{
label: "WELD1",
data: [27520,1441]
},
{
label: "WELD2",
data: [676992,555]
},
{
label: "WELD3",
data: [100,20,0]
}
]
}
I want to get result using for loop.
you can use .reduce() and do something like this:
var arr = [
{
"Material": "113/133",
"Name": [
{
"name": "WELD1",
"value": 27520
},
{
"name": "WELD2",
"value": 676992
},
{
"name": "WELD3",
"value": 421
}
]
},
{
"Material": "150/300",
"Name": [
{
"name": "WELD1",
"value": 1441
},
{
"name": "WELD2",
"value": 555
},
{
"name": "WELD3",
"value": 100992
}
]
}
];
var newArr = arr.reduce((acc, ob) => {
for (var key in ob)
if(typeof acc[key] === 'object')
acc[key] = acc[key] ? acc[key].concat(ob[key]) : [ob[key]];
else
acc[key] ? acc[key].push(ob[key]) : acc[key] = [ob[key]];
return acc;
}, {});
console.log(newArr);
let array = [
{
"Material": "113/133",
"Name": [
{
"name": "WELD1",
"value": 27520
},
{
"name": "WELD2",
"value": 676992
},
{
"name": "WELD3",
"value": 421
}
]
},
{
"Material": "150/300",
"Name": [
{
"name": "WELD1",
"value": 1441
},
{
"name": "WELD2",
"value": 555
},
{
"name": "WELD3",
"value": 100992
}
]
}
]
let answer = {Material: [], datasets: []}
array.forEach(x => {
answer.Material.push(x.Material);
x.Name.forEach(na => {
let object = answer.datasets.find(obj => obj.label === na.name) || {label: "", data: []};
if(object.label === ""){
object.label = na.name;
object.data.push(na.value);
answer.datasets.push(object);
}else{
object.data.push(na.value)
}
});
});
console.log(answer);
The above is alternative solution using forEach instead of reduce
Use of Array.reduce to build your new data structure using data you have
const start = [{
"Material": "113/133",
"Name": [{
"name": "WELD1",
"value": 27520
},
{
"name": "WELD2",
"value": 676992
},
{
"name": "WELD3",
"value": 421
}
]
},
{
"Material": "150/300",
"Name": [{
"name": "WELD1",
"value": 1441
},
{
"name": "WELD2",
"value": 555
},
{
"name": "WELD3",
"value": 100992
}
]
}
];
const end = start.reduce((tmp, {
Material,
Name,
}) => {
// Handle the material
// If it do not exist in the array, push it
if (!tmp.Material.includes(Material)) {
tmp.Material.push(Material);
}
// Handle the datasets
// Look at each Name
Name.forEach(({
name,
value,
}) => {
// Can we find the label?
const labelFind = tmp.datasets.find(y => y.label === name);
// If we can't find the label, create a new dataset
if (!labelFind) {
tmp.datasets.push({
label: name,
data: [
value,
],
});
return;
}
// If we has found it push new value in the dataset
labelFind.data.push(value);
});
return tmp;
}, {
Material: [],
datasets: [],
});
console.log(end);
// This is the old fashioned way.
// Iterate over whole array,
// make a map, push value where 'name' is found in map
// later iterate over this map - dataMap - and form required datasets array.
var Material = [];
var dataMap = {};
arr.forEach(obj => {
Material.push(obj.Material);
obj.Name.forEach(item => {
if(dataMap[item.name]){
dataMap[item.name].push(item.value);
}
else {
dataMap[item.name] = [item.value];
}
});
});
var datasets = [];
Object.keys(dataMap).forEach(label => {
datasets.push({
label: label,
data: dataMap[label]
});
});
var result = {
Material: Material,
datasets: datasets
}
console.log(result);

Categories