Rearranging JSON data to add id to nested objects - javascript

I'm trying to rearrange an incoming JSON object to use in a React component.
The JSON object I'm receiving is jsonData & this is what my current code looks like:
const jsonData = {
"Jonas": {
"position": "CTO",
"employees": [{
"Sophie": {
"position": "VP Engineering",
"employees": [{
"Nick": {
"position": "Team Lead",
"employees": [{
"Pete": {
"position": "Backend Engineer",
"employees": []
}
},
{
"Barbara": {
"position": "Fronted Engineer",
"employees": []
}
}
]
}
},
{
"Melissa": {
"position": "Product Manager",
"employees": []
}
}
]
}
}]
}
}
const userList = [jsonData]
const formatData = list =>
list.map(item => {
let name, position, employees
for (let key in item) {
name = key
position = item[key].position
employees = item[key].employees ? item[key].employees : []
}
return {
name,
position,
employees: employees ? formatData(employees) : employees
}
})
console.log(formatData(userList))
I'm trying to add new id to each object & convert the jsonData to an array. I'm getting the output but can't add the id as follows -
[
{
"id": 0,
"name": "Jonas",
"position": "CTO",
"employees": [
{
"id": 1,
"name": "Sophie",
"position": "VP Engineering",
"employees": [
{
"id": 2,
"name": "Nick",
"position": "Team Lead",
"employees": [
{
"id": 3,
"name": "Pete",
"position": "Backend Engineer",
"employees": []
},
{
"id": 4,
"name": "Barbara",
"position": "Fronted Engineer",
"employees": []
}
]
},
{
"id": 5,
"name": "Melissa",
"position": "Product Manager",
"employees": []
}
]
}
]
}
]
How can I add an id to each object of the output?

You could use Object.assign with a closure over a counter for the id.
function convert(object) {
const fn = o => (name => Object.assign(
{ id: id++, name },
o[name],
{ employees: o[name].employees.map(fn)
}))(Object.keys(o)[0]);
var id = 0;
return fn(object);
}
var data = { Jonas: { position: "CTO", employees: [{ Sophie: { position: "VP Engineering", employees: [{ Nick: { position: "Team Lead", employees: [{ Pete: { position: "Backend Engineer", employees: [] } }, { Barbara: { position: "Fronted Engineer", employees: [] } }] } }, { Melissa: { position: "Product Manager", employees: [] } }] } }] } },
result = convert(data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Simply add a var id and increment inside loop.
const jsonData = {
"Jonas": {
"position": "CTO",
"employees": [{
"Sophie": {
"position": "VP Engineering",
"employees": [{
"Nick": {
"position": "Team Lead",
"employees": [{
"Pete": {
"position": "Backend Engineer",
"employees": []
}
},
{
"Barbara": {
"position": "Fronted Engineer",
"employees": []
}
}
]
}
},
{
"Melissa": {
"position": "Product Manager",
"employees": []
}
}
]
}
}]
}
}
const userList = [jsonData]
var id=-1;
const formatData = list =>
list.map(item => {
let name, position, employees
for (let key in item) {
name = key
position = item[key].position
employees = item[key].employees ? item[key].employees : []
}
id=id+1;
return {
id,
name,
position,
employees: employees ? formatData(employees) : employees
}
})
console.log(formatData(userList))

I think this more better way and solve more nester employees array if add more
const jsonData = {
"Jonas": {
"position": "CTO",
"employees": [{
"Sophie": {
"position": "VP Engineering",
"employees": [{
"Nick": {
"position": "Team Lead",
"employees": [{
"Pete": {
"position": "Backend Engineer",
"employees": []
}
},
{
"Barbara": {
"position": "Fronted Engineer",
"employees": []
}
}
]
}
},
{
"Melissa": {
"position": "Product Manager",
"employees": []
}
}
]
}
}]
}
}
const userList = [jsonData]
const newFormat = list => {
findChildAndAddId(list, 0, list.length)
return list
}
const findChildAndAddId = (item, count, parentNumber) => {
if (item && Array.isArray(item)) {
item.map((value, index) => {
findChildAndAddId(value, count + index, item.length)
})
} else if (item) {
Object.keys(item).map(key => {
let value = item[key]
item.id = count
item.name = key
if (value.position) {
item.position = value.position
}
if (value.employees) {
item.employees = value.employees
}
delete item[key]
if (item.employees) {
findChildAndAddId(item.employees, count + parentNumber)
}
})
}
}
console.log(newFormat(userList))

Related

Form a nested tree from an array of objects in javascript

So there is array of objects of below format
let inputs = [
{
"id": "614344d9d9c21c0001e6af2e",
"groupName": "Unassigned",
"parentGroup": "null"
},
{
"id": "614447da152f69c3c1d52f2e",
"groupName": "P1",
"parentGroup": "null"
},
{
"id": "614447da152f69c3c1d52f38",
"groupName": "K1",
"parentGroup": "C1"
},
{
"id": "614447da152f69c3c1d52f3e",
"groupName": "A2",
"parentGroup": "C2"
},
{
"id": "614447da152f69c3c1d52f40",
"groupName": "G1",
"parentGroup": "P2"
},
{
"id": "614447da152f69c3c1d52f46",
"groupName": "F1",
"parentGroup": "null"
},
{
"id": "614447da152f69c3c1d52f30",
"groupName": "P2",
"parentGroup": "null"
},
{
"id": "614447da152f69c3c1d52f36",
"groupName": "C2",
"parentGroup": "P1"
},
{
"id": "614447da152f69c3c1d52f3c",
"groupName": "A1",
"parentGroup": "C2"
},
{
"id": "614447da152f69c3c1d52f34",
"groupName": "C1",
"parentGroup": "P1"
},
{
"id": "614447da152f69c3c1d52f32",
"groupName": "P3",
"parentGroup": "null"
},
{
"id": "614447da152f69c3c1d52f3a",
"groupName": "K2",
"parentGroup": "C1"
},
{
"id": "614447da152f69c3c1d52f42",
"groupName": "GG1",
"parentGroup": "G1"
},
{
"id": "614447da152f69c3c1d52f44",
"groupName": "GGG1",
"parentGroup": "GG1"
}
]
i am trying to create a tree structure of format
{name:'p1',children:[{name:'c1':children:[]}]}
so i sorted all the elements of given array considering element with parentGroup as "null" to be at the top of the array.
let finalArr = [];
inputs.sort((a,b)=> (a.parentGroup === "null") ? -1 : 1);
And for each element of the inputs array, i was iterating below logic
inputs.forEach(ele => {
if(ele.parentGroup === "null"){
let child= {name:ele.groupName,children:[]};
finalArr.push(child);
}else{
finalArr.forEach(item => {
this.findNode(item,ele);
})
}
});
If the 'parentGroup' of element is "null", then create a leaf kind of obj and push the element to 'finalArr' array
Else, then iterate across all the elements of 'finalArr' over a recursion function
public findNode(ele, obj){
if(ele.children.length === 0){
if(ele.name === obj.parentGroup){
let child = {name:obj.groupName, children:[]};
ele.children.push(child);
}
}else{
let j = ele.children.length-1;
this.findNode(ele.children[j--],obj);
}
}
This recursion function will check the element has children or not, if no children, then compare the parentGroup of given obj, with name of element from 'FinalArr'.
if so ,push the current obj to the children of the element of finalArr.
else, that is, when children has more elements, the same recursion will be triggered until depth of the element is reached.
With this i tought i would make a tree structure with given inputs array, but when a parent has more children, of same level, this logic fails,
so the inputs array has 'c1' which is a child of 'p1', but nly the child 'c2' resides, not sure the what is that i missed.
You could take a standard algorithm for getting a tree with given data
const
getTree = (data, id, parent, root, fn = o => o) => {
var t = {};
data.forEach(o => ((t[o[parent]] ??= {}).children ??= []).push(Object.assign(t[o[id]] = t[o[id]] || {}, fn(o))));
return t[root].children;
},
data = [{ id: "614344d9d9c21c0001e6af2e", groupName: "Unassigned", parentGroup: "null" }, { id: "614447da152f69c3c1d52f2e", groupName: "P1", parentGroup: "null" }, { id: "614447da152f69c3c1d52f38", groupName: "K1", parentGroup: "C1" }, { id: "614447da152f69c3c1d52f3e", groupName: "A2", parentGroup: "C2" }, { id: "614447da152f69c3c1d52f40", groupName: "G1", parentGroup: "P2" }, { id: "614447da152f69c3c1d52f46", groupName: "F1", parentGroup: "null" }, { id: "614447da152f69c3c1d52f30", groupName: "P2", parentGroup: "null" }, { id: "614447da152f69c3c1d52f36", groupName: "C2", parentGroup: "P1" }, { id: "614447da152f69c3c1d52f3c", groupName: "A1", parentGroup: "C2" }, { id: "614447da152f69c3c1d52f34", groupName: "C1", parentGroup: "P1" }, { id: "614447da152f69c3c1d52f32", groupName: "P3", parentGroup: "null" }, { id: "614447da152f69c3c1d52f3a", groupName: "K2", parentGroup: "C1" }, { id: "614447da152f69c3c1d52f42", groupName: "GG1", parentGroup: "G1" }, { id: "614447da152f69c3c1d52f44", groupName: "GGG1", parentGroup: "GG1" }],
tree = getTree(data, 'groupName', 'parentGroup', null, ({ groupName: name }) => ({ name }));
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I think the issue is how finalArr is used to generate the html elements.
When doing console.log(finalArr) it looks like the code block below. So it seems to me like the code you have to build the structure of finalArr is working fine.
// console.log(finalArr)
[
{ "name": "P3", "children": [] },
{
"name": "P2",
"children": [
{
"name": "G1",
"children": [
{ "name": "GG1", "children": [
{ "name": "GGG1", "children": [] }
]
}
]
}
]
},
{ "name": "F1", "children": [] },
{
"name": "P1",
"children": [
{ "name": "C2", "children": [
{ "name": "A1", "children": [] }
]
}
]
},
{ "name": "Unassigned", "children": [] }
]
EDIT
As OP mentioned in the comment C1 was missing. I've introduced a root element that will have the finalArr as its children and changed the findNode to use a for loop instead of forEach. In this way we can also break when we find the node and not continue recursing.
As part of the initial sorting we will sort the inputs by parentGroup so we ensure that a childs parent is added in the tree structure before we try to find it with findNode.
I believe this produces the correct result:
inputs.sort((a, b) => (a.parentGroup === "null" ? -1 : 1));
// Sort by parentGroup
let root = inputs.pop();
let inputsDescending = [root];
let max = inputs.length * inputs.length;
let c = 0;
while (inputs.length > 0 && max > c) {
const child = inputs.pop();
const hasParentGroup = inputsDescending.find(
(parent) => parent.groupName === child.parentGroup
);
if (hasParentGroup || child.parentGroup === "null") {
inputsDescending.push(child);
} else {
inputs.unshift(child);
}
}
let rootEle = { name: "root", children: [] };
inputsDescending.forEach((obj) => {
if (obj.parentGroup === "null") {
let child = { name: obj.groupName, children: [] };
rootEle.children.push(child);
} else {
findNode(rootEle, obj);
}
});
function findNode(ele, obj) {
if (ele.name === obj.parentGroup) {
let child = { name: obj.groupName, children: [] };
ele.children.push(child);
return true;
} else {
const c = ele.children.length;
if (c > 0) {
for (let i = 0; c > i; i++) {
const found = findNode(ele.children[i], obj);
if (found) break;
}
}
}
}
const finalArr = rootEle.children;
Now finalArr looks like this:
[
{ "name": "Unassigned", "children": [] },
{
"name": "P1",
"children": [
{
"name": "C1",
"children": [
{ "name": "K1", "children": [] },
{ "name": "K2", "children": [] }
]
},
{
"name": "C2",
"children": [
{ "name": "A2", "children": [] },
{ "name": "A1", "children": [] }
]
}
]
},
{ "name": "F1", "children": [] },
{
"name": "P2",
"children": [
{ "name": "G1", "children": [
{ "name": "GG1", "children": [] }
]
}
]
},
{ "name": "P3", "children": [] }
]

How to group an array of objects based on object property? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have an array like below:
let data:[
{
"class": "X",
"student":[
{
"name": "Bumblebee",
"id":"SAB77"
}
]
},
{
"class": "X",
"student":[
{
"name": "Omega",
"id":"SAB78"
}
]
},
{
"class": "IX",
"student":[
{
"name": "Pluto",
"id":"RBC17"
}
]
},
{
"class": "IX",
"student":[
{
"name":"16 psyche",
"id":"RBC18"
}
]
}
]
I want to group as following:
data:[
{
"class": "X",
"student":[
{
"name": "Bumblebee",
"id":"SAB77"
},
{
"name": "Omega",
"id":"SAB78"
}
]
},
{
"class": "IX",
"student":[
{
"name": "Pluto",
"id":"RBC17"
},
{
"name": "16 psyche",
"id":"RBC18"
}
]
}
]
let data = [
{
"class": "X",
"student":[
{
"name": "Bumblebee",
"id":"SAB77"
}
]
},
{
"class": "X",
"student":[
{
"name": "Omega",
"id":"SAB78"
}
]
},
{
"class": "IX",
"student":[
{
"name": "Pluto",
"id":"RBC17"
}
]
},
{
"class": "IX",
"student":[
{
"name":"16 psyche",
"id":"RBC18"
}
]
}
];
const output = data.reduce((acc, rec) => {
const obj = acc.find(ele => ele.class === rec.class);
if (obj) {
obj.student = [...obj.student, ...rec.student];
} else {
acc.push(rec);
}
return acc;
}, []);
console.log(output)
Try this.
let data = [
{
"class": "X",
"student": [
{
"name": "Bumblebee",
"id": "SAB77"
}
]
},
{
"class": "X",
"student": [
{
"name": "Omega",
"id": "SAB78"
}
]
},
{
"class": "IX",
"student": [
{
"name": "Pluto",
"id": "RBC17"
}
]
},
{
"class": "IX",
"student": [
{
"name": "16 psyche",
"id": "RBC18"
}
]
}
]
var reOrganized = [];
var unseen_classes = [];
for (var i = 0; i < data.length; i++) {
if (unseen_classes.indexOf(data[i].class) !== -1) {
for (var j = 0; j < reOrganized.length; j++) {
if (reOrganized[j].class === data[i].class) {
reOrganized[j].students.push(data[i].student[0])
}
}
}
else {
unseen_classes.push(data[i].class)
reOrganized.push({
class: data[i].class,
students: [data[i].student[0]]
})
}
}
console.log(reOrganized)
let data = [{
"class": "X",
"student": [{
"name": "Bumblebee",
"id": "SAB77"
}]
},
{
"class": "X",
"student": [{
"name": "Omega",
"id": "SAB78"
}]
},
{
"class": "IX",
"student": [{
"name": "Pluto",
"id": "RBC17"
}]
},
{
"class": "IX",
"student": [{
"name": "16 psyche",
"id": "RBC18"
}]
}
];
const result = data.reduce((acc, obj) => {
let existedObj = acc.length && acc.find(ele => ele.class === obj.class);
if (!acc.length || !existedObj) {
acc.push(obj);
return acc;
}
existedObj.student = [...existedObj.student, ...obj.student];
return acc;
}, []);
console.log(result);

Reorder an array from a specific data

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)

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