value got overwritten assigning json value within loop - javascript

How can I produce something like this?
{
"drink": {
"2": {
"name": "coke",
"type": "drink"
},
"3": {
"name": "coke",
"type": "drink"
}
},
"food": {
"id": "1",
"name": "1 Hour Snooker",
"type": "food"
}
}
I have problem producing multiple object under 'drink' object. It got overwritten with my below code:
http://jsfiddle.net/jLgh4at5/
var json = {
"results": {
"slots": [{
"id": "3",
"name": "pepsi",
"type": "drink"
}, {
"id": "1",
"name": "1 Hour Snooker",
"type": "food"
}, {
"id": "2",
"name": "coke",
"type": "drink"
}]
}
}
var data = {
"slots": {
}
}
json.results.slots.forEach(function (b) {
if (b["type"] == "food") {
data.slots["food"] = b;
} else {
data.slots["drink"] = b;
}
});
console.log(data);

Use array index to resolve the issue.
json.results.slots.forEach(function (b,i) {
if (b["type"] == "food") {
if(data.slots["food"])
data.slots["food"][i] = {"name":b.name,"type":"food"};
else
data.slots["food"] = {};
} else {
if(data.slots["drink"])
data.slots["drink"][i] = {"name":b.name,"type":"drink"};
else
data.slots["drink"] = {};
}
});
Or you can optimize the code as shown below.
var data = {
"slots": {
"food": {},
"drink": {}
}
};
json.results.slots.forEach(function (b,i) {
if (b["type"] == "food") {
data.slots["food"][i] = {"name":b.name,"type":"food"};
} else {
data.slots["drink"][i] = {"name":b.name,"type":"drink"};;
}
});
Here is the updated JSFiddle

Related

How do I destructure this deep nested json objects and map it in JS

I have a nested array like below. There are about 100 de objects in the array. The de objects also have deg[0] array but most likely I will only have the first index. Now the trick is that the de are subset of deg. Which means each deg can have say 10 de. How can I retrieve the deg and there associated de and map it into a new array like:
newArray = [
deg1: [
{de1},
{de2}
],
deg2: [
{de1},
{de2}
]
]
Here is my nested array. I posted four but the list is over a 100.
{
"name": "Report",
"id": "2YYUEZ6I1r9",
"dse1": [
{
"de1": {
"name": "Number",
"id": "HjMOngg3kuy",
"de1-av": [
{
"value": "FHaQMPv9zc7",
"attribute": {
"id": "uwVkIP7PZDt"
}
},
{
"value": "something",
"attribute": {
"id": "FHaQMPv9zc7"
}
}
],
"deg1": [
{
"name": "TB",
"id": "2XJB1JO9qX8"
}
]
}
},
{
"de2": {
"name": "Number of",
"id": "a3dtGETTawy",
"de2-av": [
{
"value": "FHaQMPv9zc7",
"attribute": {
"id": "uwVkIP7PZDt"
}
},
{
"value": "something",
"attribute": {
"id": "FHaQMPv9zc7"
}
}
],
"deg1": [
{
"name": "Secondary",
"id": "w99RWzXHgtw"
}
]
}
},
{
"de1": {
"name": "Number of",
"id": "a3dtGETTawy",
"de1av": [
{
"value": "FHaQMPv9zc7",
"attribute": {
"id": "uwVkIP7PZDt"
}
},
{
"value": "something",
"attribute": {
"id": "FHaQMPv9zc7"
}
}
],
"deg2": [
{
"name": "Secondary",
"id": "w99RWzXHgtw"
}
]
}
},
{
"de2": {
"name": "Number of",
"id": "a3dtGETTawy",
"de2av": [
{
"value": "FHaQMPv9zc7",
"attribute": {
"id": "uwVkIP7PZDt"
}
},
{
"value": "something",
"attribute": {
"id": "FHaQMPv9zc7"
}
}
],
"deg2": [
{
"name": "Tertiary",
"id": "w99RWzXHgtw"
}
]
}
}
]
}
Group array of objects by property (this time a property to be matched by a reg exp) using Array.reduce.
Update: Ignoring missing keys.
var input={name:"Report",id:"2YYUEZ6I1r9",dse1:[{de1:{name:"Number",id:"HjMOngg3kuy","de1-av":[{value:"FHaQMPv9zc7",attribute:{id:"uwVkIP7PZDt"}},{value:"something",attribute:{id:"FHaQMPv9zc7"}}],deg1:[{name:"TB",id:"2XJB1JO9qX8"}]}},{de2:{name:"Number of",id:"a3dtGETTawy","de2-av":[{value:"FHaQMPv9zc7",attribute:{id:"uwVkIP7PZDt"}},{value:"something",attribute:{id:"FHaQMPv9zc7"}}],deg1:[{name:"Secondary",id:"w99RWzXHgtw"}]}},{de1:{name:"Number of",id:"a3dtGETTawy",de1av:[{value:"FHaQMPv9zc7",attribute:{id:"uwVkIP7PZDt"}},{value:"something",attribute:{id:"FHaQMPv9zc7"}}],deg2:[{name:"Secondary",id:"w99RWzXHgtw"}]}},{de2:{name:"Number of",id:"a3dtGETTawy",de2av:[{value:"FHaQMPv9zc7",attribute:{id:"uwVkIP7PZDt"}},{value:"something",attribute:{id:"FHaQMPv9zc7"}}],deg2:[{name:"Tertiary",id:"w99RWzXHgtw"}]}}]}
var reg = new RegExp("^de[0-9]+$");
var reg2 = new RegExp("^deg[0-9]+$");
let obj = input['dse1'].reduce(function(agg, item) {
// do your group by logic below this line
var key = Object.keys(item).find(function(key) {
return key.match(reg) ? key : null;
})
if (key) {
var key2 = Object.keys(item[key]).find(function(key) {
return key.match(reg2) ? key : null;
})
agg[key] = agg[key] || [];
if (key2) {
var to_push = {}
to_push[key2] = item[key][key2]
agg[key].push(to_push)
}
}
// do your group by logic above this line
return agg
}, {});
console.log(obj)
.as-console-wrapper {
max-height: 100% !important;
}

map values to an array inside an object

I have this object below
{
"root": {
"data": {
"page": 1,
"contents": [
{
"node": {
"id": "UzpfSTE",
"stats": {
"viewers": {
"nodes": [
{
"id": "1",
"name": "John"
},
{
"id": "2",
"name": "Shaun"
}
]
}
}
}
},
{
"node": {
"id": "UzpfSTG",
"stats": {
"viewers": {
"nodes": [
{
"id": "3",
"name": "Liam"
}
]
}
}
}
}
]
}
}
}
There is contents node, each of them will have many viewers, all I want is to extract all viewers name to an array, in this instance my result will be [John, Shaun, Liam]
I have this approach:
const data = JSON.parse(rt)
const contents = data.root.data.contents
const newArray = []
for (i = 0; i < contents.length; i++) {
arr2 = contents[i].node.stats.viewers.nodes
for (n = 0; n < arr2.length; n++) {
name = arr2[n].name
newArray.push(name)
}
}
console.log(newArray)
>>> [John, Shaun, Liam]
Which does the job, but occasionaly the object key names change and I have to alter everytime.
So is there more elegant way to do this?
You can simplify that imperative logic like this.
I don't understand what you mean by "the object key names change" though
const data = {
"root": {
"data": {
"page": 1,
"contents": [{
"node": {
"id": "UzpfSTE",
"stats": {
"viewers": {
"nodes": [{
"id": "1",
"name": "John"
},
{
"id": "2",
"name": "Shaun"
}
]
}
}
}
},
{
"node": {
"id": "UzpfSTG",
"stats": {
"viewers": {
"nodes": [{
"id": "3",
"name": "Liam"
}]
}
}
}
}
]
}
}
}
const names = data.root.data.contents.flatMap(({
node: {
stats: {
viewers: {
nodes
}
}
}
}) => nodes.map(({
name
}) => name))
console.log(names)
const data = JSON.parse(rt)
const contents = data.root.data.contents
const viewers = contents.map(item => item.node.stats.viewers.nodes).flat()
const viewerNames = viewers.map(viewer => viewer.name)

JavaScript :: Iterate through nested JSON object and create new structure

Attempting to restructure nested JSON data (data1) into "proper" format (data2)
with no success so far.
data1 is generated based on a given parent directory (recipes) that looks for html files.
data2 is what I'm trying to output using data1 since whatever content inside a folder is better represented as array of objects than just pure nested objects.
var data1 = {
"cake": {
"chocolate": {
"black-forest": {
"name": "Black Forest",
"path": "recipes/cake/chocolate/black-forest.html"
},
"new-shortcake": {
"milk-chocolate-shortcake": {
"name": "Milk chocolate shortcake",
"path": "recipes/cake/chocolate/shortcake/milk-chocolate-shortcake.html"
},
"dark-chocolate-shortcake": {
"name": "Dark chocolate shortcake",
"path": "recipes/cake/chocolate/shortcake/dark-chocolate-shortcake.html"
}
}
}
},
"pasta": {
"spaghetti": {
"aglio-olio": {
"name": "Spagehetti Aglio Olio",
"path": "recipes/pasta/spaghetti/aglio-olio.html"
},
"carbonara": {
"name": "Carbonara",
"path": "recipes/pasta/spaghetti/carbonara.html"
}
},
"lasagna": {
"name": "Lasagna",
"path": "recipes/pasta/lasagna.html"
}
}
}
var data2 = [
{
"name": "cake",
"children": [
{
"name": "chocolate",
"children": [
{
"name": "Black Forest",
"path": "recipes/cake/chocolate/black-forest.html"
},
{
"name": "New Shortcake",
"children": [
{
"name": "Milk chocolate shortcake",
"path": "recipes/cake/chocolate/shortcake/milk-chocolate-shortcake. html"
},
{
"name": "Dark chocolate shortcake",
"path": "recipes/cake/chocolate/shortcake/dark-chocolate-shortcake. html"
}
]
}
]
}
]
},
{
"name": "pasta",
"children": [
{
"name": "spaghetti",
"children": [
{
"name": "Spagehetti Aglio Olio",
"path": "recipes/pasta/spaghetti/aglio-olio.html"
},
{
"name": "Carbonara",
"path": "recipes/pasta/spaghetti/carbonara.html"
}
]
},
{
"name": "Lasagna",
"path": "recipes/pasta/lasagna.html"
}
]
}
]
https://codepen.io/kyooriouskoala/pen/LLLXmG
Any help much appreciated!
PS: End goal is to build a menu with the new data structure.
I hope this output is what you meant.
var final = [];
function tree(object, temp){
for(var key in object){
var folder = {};
if(object[key] !== null && typeof object[key] == 'object'){
//console.log(key);
if(_.has(object[key], "path")){
folder.name = object[key].name;
folder.path = object[key].path;
folder.children = [];
} else{
folder.name = key;
folder.children = object[key];
}
final.push(folder);
tree(object[key]);
}
}
return final;
}
This outputs your data as a associative object with values needed.

Javascript get name from data by id function

I need to create a function the would return the name of the car when given the id.
I have this data:
{
"cars": [
{
"id": "661",
"name": "ford"
},
{
"id": "657",
"name": "fiat",
},
{
"id": "654",
"name": "volvo",
},
{
"id": "653",
"name": "porche",
},
{
"id": "650",
"name": "mazda",
}
]
}
So I've done this:
function getCarNameFromId(id) {
theData = {
"cars": [
{
"id": "661",
"name": "ford"
},
{
"id": "657",
"name": "fiat",
},
{
"id": "654",
"name": "volvo",
},
{
"id": "653",
"name": "porche",
},
{
"id": "650",
"name": "mazda",
}
]
};
console.log(theData.name);
}
then call it:
function getCarNameFromId('650');
How do I finish this code so I can get the code to return me the name of the id specified?
JS solution
var findCar = function(id) {
var theData = {
"cars": [{
"id": "661",
"name": "ford"
},
{
"id": "657",
"name": "fiat",
},
{
"id": "654",
"name": "volvo",
},
{
"id": "653",
"name": "porche",
},
{
"id": "650",
"name": "mazda",
}
]
};
for (var i = 0; i < theData.cars.length; i++) {
var car = theData.cars[i];
if (car.id === id)
return car.name;
}
}
console.log(findCar("654"));
If you are using any mordenr browser you can use find method to find object from array
function getCarNameFromId(id) {
......
..........
.....
var obj = theData.cars.find( function(el) {
return el.id == id
})
if(obj){
return obj.name
} else {
return ''; // or just without any value.
}
}
if still want to support old browsers i would recommand to use lodash.js or underscore.js
cars.find(car => car.id === id).name
Reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Underscore Convert array to object keys

I am trying to convert this array to an object. Using underscore, I want to convert this array :
[
{
"id": "parentA",
"children": [
{
"name": "name1"
},
{
"name": "name2"
},
{
"name": "name3"
}
]
},
{
"id": "parentB",
"children": [
{
"name": "name4"
},
{
"name": "name5"
},
{
"name": "name6"
}
]
}]
into an object that looks like this:
{
"name1": "parentA",
"name2": "parentA",
"name3": "parentA",
"name4": "parentB",
"name5": "parentB",
"name6": "parentB"
}
I'm really just looking for the cleanest/simplest way possible.
Here's a fairly short way to do it with two reduce:
var data = [
{
"id": "parentA",
"children": [
{
"name": "name1"
},
{
"name": "name2"
},
{
"name": "name3"
}
]
},
{
"id": "parentB",
"children": [
{
"name": "name4"
},
{
"name": "name5"
},
{
"name": "name6"
}
]
}];
var out = _.reduce(data, function(result, parent) {
_.reduce(parent.children, function(r, child) {
r[child.name] = parent.id;
return r;
}, result);
return result;
}, {});
document.write(JSON.stringify(out));
<script src="http://underscorejs.org/underscore-min.js"></script>
var a = [{
"id": "parentA",
"children": [{
"name": "name1"
}, {
"name": "name2"
}, {
"name": "name3"
}]
}, {
"id": "parentB",
"children": [{
"name": "name4"
}, {
"name": "name5"
}, {
"name": "name6"
}]
}];
var new_obj = {};
var len = a.length;
for (j = 0; j < len; j++) {
var c = $.extend({}, a[j]);
var children_length = (c.children).length;
for (i = 0; i < children_length; i++) {
var temp = ((a[j].children)[i]).name;
new_obj[temp] = c.id;
}
}
document.write(JSON.stringify(new_obj));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You'll only need to use underscore if you're supporting browsers without native reduce and forEach array methods, but you can do it like this.
var result = _.reduce(array, function(memo, entry) {
_.each(entry.children, function(child) {
memo[child.name] = entry.id;
});
return memo;
}, {});
function expand(list){
return _.reduce(list,function(a,b) {
_.each(b.children, function(c) {
a[c.name] = b.id;
});
return a;
},{});
}
Check the output for your sample here

Categories

Resources