JSON conversion with JavaScript - javascript

This is the data I received from API but It not works with DevExtreme Grid well so I want to convert this JSON:
[{
"name" : "Cedrick Wyman",
"id" : "9101",
"children" : [ {
"name" : "Ursula Hirthe",
"id" : "9106",
"children" : [ {
"name" : "Viviane Breitenberg",
"id" : "11651"
} ]
}, {
"name" : "Twila Erdman",
"id" : "9102",
"children" : [ {
"name" : "Zion Volkman",
"id" : "9105"
}, {
"name" : "Lauryn Leannon",
"id" : "9104"
} ]
} ]
}]
To something like this with Javascript. I want to remove 'children' and move them outside
[ {
"name" : "Cedrick Wyman",
"id" : "9101"
},
{ "name" : "Ursula Hirthe",
"id" : "9106"
},
{
"name" : "Viviane Breitenberg",
"id" : "11651"
},
{
"name" : "Twila Erdman",
"id" : "9102"
},
{
"name" : "Zion Volkman",
"id" : "9105"
},
{
"name" : "Lauryn Leannon",
"id" : "9104"
}
]
How can I do this? Sorry for my bad English! Thanks a lot!

You can call .flatMap() on your array by mapping to an array of objects, which recursively calls .flatMap() on children to further get the {name, id} objects from your children array:
const arr = [{ "name": "Cedrick Wyman", "id": "9101", "children": [{ "name": "Ursula Hirthe", "id": "9106", "children": [{ "name": "Viviane Breitenberg", "id": "11651" }] }, { "name": "Twila Erdman", "id": "9102", "children": [{ "name": "Zion Volkman", "id": "9105" }, { "name": "Lauryn Leannon", "id": "9104" }] }] }];
const res = arr.flatMap(function inner({name, id, children = []}) {
return [{name, id}, ...children.flatMap(inner)];
});
console.log(res);
An alternative without .flatMap() for better browser support would be to use the following:
const arr = [{ "name": "Cedrick Wyman", "id": "9101", "children": [{ "name": "Ursula Hirthe", "id": "9106", "children": [{ "name": "Viviane Breitenberg", "id": "11651" }] }, { "name": "Twila Erdman", "id": "9102", "children": [{ "name": "Zion Volkman", "id": "9105" }, { "name": "Lauryn Leannon", "id": "9104" }] }] }];
const res = [].concat.apply([], arr.map(function inner(o) {
return [].concat.apply({name: o.name, id: o.id}, (o.children || []).map(inner));
}));
console.log(res);

The answer with flatMap is NOT supported on Internet Explorer, however my solution will work everywhere regardless of browser or server-side code.
Plus, This is more easily understandable code. You call a function recursively, until there are no children keys left in any of the items in the list.
For each item, append the name/id to flatList and if children are present, recursion starts and whatever is returned is appended to flatList preserve the desired order.
const json = [{
"name" : "Cedrick Wyman",
"id" : "9101",
"children" : [ {
"name" : "Ursula Hirthe",
"id" : "9106",
"children" : [ {
"name" : "Viviane Breitenberg",
"id" : "11651"
} ]
}, {
"name" : "Twila Erdman",
"id" : "9102",
"children" : [ {
"name" : "Zion Volkman",
"id" : "9105"
}, {
"name" : "Lauryn Leannon",
"id" : "9104"
} ]
} ]
}];
const getFlattenedList = function (unflattenedList) {
if (!(Array.isArray(unflattenedList) && unflattenedList.length)) return;
let flatList = [];
for (let i = 0; i < unflattenedList.length; i += 1) {
const item = unflattenedList[i];
flatList = flatList.concat({ name: item.name, id: item.id });
if (Array.isArray(item.children) && item.children.length) {
flatList = flatList.concat(getFlattenedList(item.children));
}
}
return flatList;
};
console.log(getFlattenedList(json));

You can do something like this:
const data = `[{
"name" : "Cedrick Wyman",
"id" : "9101",
"children" : [ {
"name" : "Ursula Hirthe",
"id" : "9106",
"children" : [ {
"name" : "Viviane Breitenberg",
"id" : "11651"
} ]
}, {
"name" : "Twila Erdman",
"id" : "9102",
"children" : [ {
"name" : "Zion Volkman",
"id" : "9105"
}, {
"name" : "Lauryn Leannon",
"id" : "9104"
} ]
} ]
}]`;
const dataJSON = JSON.parse(data);
const newData = [];
for (let e of dataJSON) {
newData.push({ name: e.name, id: e.id });
for (let child1 of e.children) {
newData.push({ name: child1.name, id: child1.id });
for (let child2 of child1.children) {
newData.push({ name: child2.name, id: child2.id });
}
}
}
console.log(newData);

Related

Get the value of specific fields in an array based on a condition

I have an array below.
For each "_id" in each object element in this array, there is an array called "form".
What I would like to get is the answerValue for each _id, where the field value in form is cState.
let array = [{
"_id" : "a1",
"user" : "John",
"form" : [
{
"question" : "question1",
"questionValue" : "Which state do you live in?",
"answers" : [
"answer1"
],
"answerValue" : [
"Arizona"
],
"field" : "cState",
},
{
"question" : "question2",
"questionValue" : "What is your nationality?",
"answers" : [
"answer2"
],
"answerValue" : [
"American"
],
"field" : "nationality",
},
"_id" : "a2",
"user" : "Mike",
"form" : [
{
"question" : "question1",
"questionValue" : "Which state do you live in?",
"answers" : [
"answer3"
],
"answerValue" : [
"Florida"
],
"field" : "cState",
},
{
"question" : "question2",
"questionValue" : "What is your nationality?",
"answers" : [
"answer2"
],
"answerValue" : [
"American"
],
"field" : "nationality",
},
}]
Expected Output
[{
"_id" : "a1",
"user" : "John",
"answerValue": "Arizona"
},
{
"_id" : "a2",
"user" : "Mike",
"answerValue": "Florida"
},
]
Here's what I tried:
let allDemographics
allDemographics = array.map((item) => {
return {
user: item.array._id,
nationality: item.array.nationality,
state: item.array.form,
}
})
Try it :
let array = [
{
"_id" : "a1",
"user" : "John",
"form" : [
{
"question" : "question1",
"questionValue" : "Which state do you live in?",
"answers" : [
"answer1"
],
"answerValue" : [
"Arizona"
],
"field" : "cState",
},
{
"question" : "question2",
"questionValue" : "What is your nationality?",
"answers" : [
"answer2"
],
"answerValue" : [
"American"
],
"field" : "nationality",
}
]
},
{
"_id" : "a2",
"user" : "Mike",
"form" : [
{
"question" : "question1",
"questionValue" : "Which state do you live in?",
"answers" : [
"answer3"
],
"answerValue" : [
"Florida"
],
"field" : "cState",
},
{
"question" : "question2",
"questionValue" : "What is your nationality?",
"answers" : [
"answer2"
],
"answerValue" : [
"American"
],
"field" : "nationality",
},
]
}
]
let allDemographics = array.map((item) => {
let fieldCstate = item.form.find(form => form.field === "cState")
return {
_id: item._id,
user: item.user,
answerValue: fieldCstate.answerValue[0],
}
})
console.log(allDemographics)
This one I like because you filter before you map. If you had a large array this might give you better performance:
let arr = array.filter(x => x.form.every(y => y.field === "cState"));
const data = arr.map((x) => ({ user: x.user, id: x._id,
answer:x.form[0].answerValue }));
console.log(data[0].answer)
Or a one liner:
let arr = array.filter(x => x.form.every(y => y.field === "cState"))
.map(x => ({ user: x.user, id: x._id, answer:x.form[0].answerValue })
)

fetch data which come from firebse

I just wanted to fetch that data which coming from this https://food-ordring-af14d-default-rtdb.firebaseio.com/order the data is in the form of JSON and it looks like that
{
"-MzJLd0sSssh9tbJbjUS" : {
"orderDetails" : [ {
"amount" : 4,
"id" : "m1",
"name" : "Shushi",
"price" : 22.99
}, {
"amount" : 3,
"id" : "m2",
"name" : "Schnitzel",
"price" : 16.5
} ],
"user" : {
"address" : "A-132 shiv vihar,rishal garden,Nangloi",
"city" : "New delhi",
"name" : "Bhupender Sharma",
"postal" : "110041"
}
},
"-MzJOf_52xhRQi3izTRV" : {
"orderDetails" : [ {
"amount" : 2,
"id" : "m3",
"name" : "Barbecue Burger",
"price" : 12.99
}, {
"amount" : 2,
"id" : "m4",
"name" : "Green Bowl",
"price" : 18.99
} ],
"user" : {
"address" : "Nangloi",
"city" : "New delhi",
"name" : "ANkit",
"postal" : "445575"
}
}
}
Try this code .. here some example
const fetchdata = async()=>{
const response = await fetch('https://jsonplaceholder.typicode.com/todos')
const jdata = await response.json()
console.log(jdata)
}
fetchdata()

Add New key at the end of each object inside an array

I have data from mongodb like this from one collection.
/* 1 */
{
"_id" : ObjectId("5be94355f220b62c7449dc0f"),
"districts" : [
{
"name" : "NORTH AND MIDDLE",
"code" : 632.0
},
{
"name" : "EAST",
"code" : 603.0
},
{
"name" : "SOUTH",
"code" : 602.0
}
],
"state" : "ISLANDS"
}
/* 2 */
{
"_id" : ObjectId("5be94355f220b62c7441dc04"),
"districts" : [
{
"name" : "Apple",
"code" : 512.0
},
{
"name" : "Ball",
"code" : 522.0
}
],
"state" : "GOLD"
}
/* 3 */
{
"_id" : ObjectId("5eee07816a011d391a45178"),
"districts" : [
{
"name" : "DAM",
"code" : 478.0
},
{
"name" : "DEN",
"code" : 481.0
},
{
"name" : "DOG AND CAT",
"code" : 461.0
}
],
"state" : "THE NAGAR AND HAVELI"
}
I was given an excel sheet like below as shown with no other information only 2 columns
My work is to add "Short Name of District" for all districts.
I tried below method
var tc = [
"NORTH AND MIDDLE",
"EAST",
"SOUTH",
"Apple",
"Ball ",
"DAM ",
"DEN ",
"DOG AND CAT"
]
db.dummy.find({"districts.name":{$in:tc}}).forEach(x => {
x["districts"].forEach( y => {
if (
y.name == "NORTH AND MIDDLE" ){
y.short_name = "NAM"
}
if (
y.name == "EAST" ){
y.short_name = "ET"
}
if (
y.name == "SOUTH" ){
y.short_name = "ST"
}
})
})
I got the result
/* 1 */
{
"_id" : ObjectId("5be94355f220b62c7449dc0f"),
"districts" : [
{
"name" : "NORTH AND MIDDLE",
"code" : 632.0,
"short_name" : "NAM"
},
{
"name" : "EAST",
"code" : 603.0,
"short_name" : "ET"
},
{
"name" : "SOUTH",
"code" : 602.0,
"short_name" : "ST"
}
],
"state" : "ISLANDS"
}
/* 2 */
{
"_id" : ObjectId("5be94355f220b62c7441dc04"),
"districts" : [
{
"name" : "Apple",
"code" : 512.0,
"short_name" : "Al"
},
{
"name" : "Ball",
"code" : 522.0
"short_name" : "BA"
}
],
"state" : "GOLD"
}
/* 3 */
{
"_id" : ObjectId("5eee07816a011d391a45178"),
"districts" : [
{
"name" : "DAM",
"code" : 478.0,
"short_name" : "DA"
},
{
"name" : "DEN",
"code" : 481.0,
"short_name" : "DN"
},
{
"name" : "DOG AND CAT",
"code" : 461.0
"short_name" : "DAC"
}
],
"state" : "THE NAGAR AND HAVELI"
}
Is this is the only method ??
like using if loop for all districts or any other methods are there like using mongodb aggregate or any other javascript methods. It will be helpful if other methods are there as it will be problem to use if loop when there is 730 districts are there. I dont have experience in working with aggregate frameworks so i thought anyone might know other method.
You may write a mapping:
const districtNameToShort = {
'NORTH AND MIDDLE': 'NAM',
'EAST': 'ET',
...
}
Then in your forEach
const districtNameToShort = {
'NORTH AND MIDDLE': 'NAM',
'EAST': 'ET'
}
db.dummy.find().forEach(x => {
db.dummy.update(
{_id : x._id},
{$set: {
districts: x.districts.map(district => {
district.short_name = districtNameToShort[district.name] || district.name
return district
})
}}
)
})

Concatenate object's properties of variable length of a JavaScript object into a new property of the object

I have this complicated object structure:
myObject = {
"myObject" : [
{
"id" : 1,
"parameters" : [
{
"name" : "name1",
"special" : "xxx"
},
{
"name" : "name2",
"special" : "yyy"
}
]
},
{
"id" : 2,
"parameters" : [
{
"name" : "name3",
"special" : "zzz"
}
]
},
{
"id" : 2,
"parameters" : [
{
"name" : "name4",
"special" : "ttt"
},
{
"name" : "name5",
"special" : "aaa"
},
{
"name" : "name6",
"special" : "zzz"
}
]
},
...
]
};
It consists of a array of other objects, each of them having a variable number of parameters.
My goal is to concatenate the special of parameters of each object into a new string which must be stored as new property of it.
In this case, the result should look like:
myObject = {
"myObject" : [
{
"id" : 1,
"parameters" : [
{
"name" : "name1",
"special" : "xxx"
},
{
"name" : "name2",
"special" : "yyy"
}
],
"newProp" : "xxxyyy"
},
{
"id" : 2,
"parameters" : [
{
"name" : "name3",
"special" : "zzz"
}
],
"newProp" : "zzz"
},
{
"id" : 2,
"parameters" : [
{
"name" : "name4",
"special" : "ttt"
},
{
"name" : "name5",
"special" : "aaa"
},
{
"name" : "name6",
"special" : "zzz"
}
],
"newProp" : "tttaaazzz"
},
...
]
};
I tried something like this:
forEach(arr in myObject.myObject){
arr.parameters(forEach (i in arr.parameters.special) {
myObject.myObject = i.concat(myObject.myObject);
})
}
obviously, it does not work. But I guess that this could be the right approach.
Any suggestions?
You can loop through the object using Array#forEach and then construct the string based on parameter values using Array#map and Array#join, like this:
const myObject = {"myObject":[{"id":1,"parameters":[{"name":"name1","special":"xxx"},{"name":"name2","special":"yyy"}]},{"id":2,"parameters":[{"name":"name3","special":"zzz"}]},{"id":2,"parameters":[{"name":"name4","special":"ttt"},{"name":"name5","special":"aaa"},{"name":"name6","special":"zzz"}]}]};
myObject.myObject.forEach(item => {
item.newProp = item.parameters.map(p => p.special).join('');
});
console.log(myObject);
Use reduce and for Each
var myObject = {
"myObject" : [
{
"id" : 1,
"parameters" : [
{
"name" : "name1",
"special" : "xxx"
},
{
"name" : "name2",
"special" : "yyy"
}
]
},
{
"id" : 2,
"parameters" : [
{
"name" : "name3",
"special" : "zzz"
}
]
},
{
"id" : 2,
"parameters" : [
{
"name" : "name4",
"special" : "ttt"
},
{
"name" : "name5",
"special" : "aaa"
},
{
"name" : "name6",
"special" : "zzz"
}
]
}
]
};
myObject.myObject.forEach(arr => {
arr.prop = arr.parameters.reduce((res,obj)=> res+obj.special, '')
})
console.log(myObject)
You can use .map() and .reduce() like this:
let myObject = [{"id" : 1, "parameters" : [{ "name" : "name1", "special" : "xxx"}, { "name" : "name2", "special" : "yyy" }]}, { "id" : 2, "parameters" : [{ "name" : "name3", "special" : "zzz"}]}, {"id" : 2, "parameters" : [{ "name" : "name4", "special" : "ttt"}, { "name" : "name5", "special" : "aaa"},{ "name" : "name6", "special" : "zzz"}]}];
let result = myObject.map(
o => (o.newProp = o['parameters'].reduce((a, o) => a + o['special'], ""), o)
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
One more way is to use nested map functions:
myObject = {"myObject":[{"id":1,"parameters":[{"name":"name1","special":"xxx"},{"name":"name2","special":"yyy"}]},{"id":2,"parameters":[{"name":"name3","special":"zzz"}]},{"id":2,"parameters":[{"name":"name4","special":"ttt"},{"name":"name5","special":"aaa"},{"name":"name6","special":"zzz"}]}]};
myObject.myObject.map(x => {
x.newProp = x.parameters.map(p => p.special).join('');
return x;
})
console.log(myObject);

cannot use the part (stats of stats.cat3.detail.name) to traverse the element. nested objects and arrays

I'm able to do
db.getCollection('comps').find({"stats.cat3.detail.name" : "Friendlyness"})`
This shows the proper docs the have a name of "Friendlyness" in the detail array.
I wanted to change "Friendlyness" to "friendliness"
I tried :
db.getCollection('comps').update(
{"stats.cat3.detail.name" : "Friendlyness"},
{$set : {"stats.cat3.detail.name" : "Friendliness"} }
)
and got errors like
" cannot use the part (stats of stats.cat3.detail.name) to traverse the element ({stats: [ { cat3: ...."
I tried putting in position operators "$" all over the update object property. but still get errors.
sample data:
{
"_id" : ObjectId("58d94c441eb9e52454932db6"),
"desc" : "Manufacturer of a wide range of consumer electronics products including audio, video, communications, and computer systems.",
"source" : "alexa",
"category" : "Consumer Electronics",
"name" : "comp1.com",
"__v" : 0,
"stats" : [
{
"cat1" : {
"detail" : [
{
"value" : [
{
"data" : 1,
"name" : "quick service"
}
],
"name" : "Time on hold"
},
{
"value" : [
{
"data" : 1,
"name" : "some words but strong accent"
},
{
"data" : 1,
"name" : "EZ to understand"
}
],
"name" : "Language fluency"
},
{
"value" : [
{
"data" : 1,
"name" : "Yes"
}
],
"name" : "Human answered"
},
{
"value" : [
{
"data" : 2,
"name" : "Like a hot potato"
},
{
"data" : 1,
"name" : "1 or 2 times"
}
],
"name" : "Transfered alot"
},
{
"value" : [
{
"data" : 3,
"name" : "ok time"
},
{
"data" : 1,
"name" : "quick service"
},
{
"data" : 1,
"name" : "short time"
}
],
"name" : "Time on Hold"
},
{
"value" : [
{
"data" : 1,
"name" : "some word but strong accent"
},
{
"data" : 2,
"name" : "EZ to understand"
}
],
"name" : "Language Fluency"
},
{
"value" : [
{
"data" : 2,
"name" : "Yes"
}
],
"name" : "Human Answered"
}
],
"average" : 81
},
"cat2" : {
"detail" : [
{
"value" : [
{
"data" : 1,
"name" : "It was ok"
},
{
"data" : 1,
"name" : "Not EZ at all"
},
{
"data" : 7,
"name" : "there were hidden gimicks"
},
{
"data" : 2,
"name" : "It was OK"
},
{
"data" : 1,
"name" : "Found Quickly"
}
],
"name" : "Easy to find desired product"
},
{
"value" : [
{
"data" : 1,
"name" : "Easy to understand"
},
{
"data" : 1,
"name" : "Eventually understood"
}
],
"name" : "Clear information about the product"
},
{
"value" : [
{
"data" : 2,
"name" : "none"
},
{
"data" : 3,
"name" : "There was but won't complain"
},
{
"data" : 1,
"name" : "Very Bad"
}
],
"name" : "Annoying popups"
},
{
"value" : [
{
"data" : 4,
"name" : "Eventually Understood"
},
{
"data" : 1,
"name" : "EZ to understand"
}
],
"name" : "Clear data about the product"
}
],
"average" : 71
},
"cat3" : {
"detail" : [
{
"value" : [
{
"data" : 1,
"name" : "Very quick"
}
],
"name" : "Prompteness"
},
{
"value" : [
{
"data" : 3,
"name" : "We're cool"
},
{
"data" : 4,
"name" : "They didn't like me"
}
],
"name" : "Friendlyness"
},
{
"value" : [
{
"data" : 3,
"name" : "Very Confusing"
},
{
"data" : 2,
"name" : "Still a little confused"
},
{
"data" : 3,
"name" : "Enlightened"
}
],
"name" : "Knowledge"
},
{
"value" : [
{
"data" : 3,
"name" : "On hold too many times"
}
],
"name" : "Promptness"
}
],
"average" : 69
}
}
]
}

Categories