how to get all nested child array object - javascript

{
"name":"123",
"reponsetype":"2",
"ussdcode":"123",
"parrentussd":"0",
"children": [
{
"name":"1 Menu",
"reponsetype":"2",
"ussdcode":"123*1",
"parrentussd":"123"
},
{
"name":"Menu 2",
"reponsetype":"2",
"ussdcode":"123*2",
"parrentussd":"123",
"children":[
{
"name":"Dynamic Menu 1",
"reponsetype":"4",
"ussdcode":"123*2",
"parrentussd":"123*2"
}
]
}

You can do it using recursion.
Try this:
let arr = { "name": "123", "reponsetype": "2", "ussdcode": "123", "parrentussd": "0", "children": [{ "name": "1 Menu", "reponsetype": "2", "ussdcode": "123*1", "parrentussd": "123" }, { "name": "Menu 2", "reponsetype": "2", "ussdcode": "123*2", "parrentussd": "123", "children": [{ "name": "Dynamic Menu 1", "reponsetype": "4", "ussdcode": "123*2", "parrentussd": "123*2" }] }] }
let res = [];
function getChild(obj) {
for (let i = 0; i < obj.children.length; i++) {
if (obj.children[i].children) {
getChild(obj.children[i]);
delete obj.children[i].children;
res.push(obj.children[i])
} else {
res.push(obj.children[i])
}
}
}
getChild(arr);
console.log(res);

Related

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);

Looping through complex and nested JSON using this example json

I'm trying to loop a complex/nested JSON object. I'm trying to loop var_color.color.primary.
Questions:
What causes this error?
Cannot read property '_id' of undefined
How can I output the primary?
Kindly use only vanilla Javascript.
Example Data
products.json file
{
"products": [
{
"_id": "000",
"name": "Name 1",
"description": "Long description 1"
},
{
"_id": "001",
"name": "Name 2",
"description": "Long description 2",
"var_color": {
"_id": "12341",
"color": {
"primary": "pink",
"secondary": "penk"
}
}
},
{
"_id": "002",
"name": "Name 3",
"description": "Long description 3"
},
{
"_id": "003",
"name": "Name 4",
"description": "Long description 4",
"var_color": {
"_id": "12342",
"color": {
"primary": "red",
"secondary": "rid"
}
}
}
],
"categories": []
}
// main.js
async function getData(product) {
let response = await fetch(`./api/products/${product}`);
let data = await response.json();
return data;
}
getData('products.json').then(data => {
for (let i in data.products) {
let all = data.products[i];
let name = all.name;
let description = all.description;
console.log(name);
console.log(description);
for (let j in all) {
let variantColor = all.var_color[j].primary;
console.log(variantColor);
}
}
});
This is my current script as of the moment.
all.var_color does not exist in each entry, therefore you need to check for its presence.
You are treating all.var_color[j] as if it were an array, but it is an object.
To get the primary color, replace the inner loop (for (let j in all)) with a simple test:
if(all.var_color) {
let variantColor = all.var_color.color.primary;
console.log(variantColor);
}
var data = {
"products": [
{
"_id": "000",
"name": "Name 1",
"description": "Long description 1"
},
{
"_id": "001",
"name": "Name 2",
"description": "Long description 2",
"var_color": {
"_id": "12341",
"color": {
"primary": "pink",
"secondary": "penk"
}
}
},
{
"_id": "002",
"name": "Name 3",
"description": "Long description 3"
},
{
"_id": "003",
"name": "Name 4",
"description": "Long description 4",
"var_color": {
"_id": "12342",
"color": {
"primary": "red",
"secondary": "rid"
}
}
}
],
"categories": []
};
for (let i in data.products) {
let all = data.products[i];
let name = all.name;
let description = all.description;
console.log(name);
console.log(description);
if(all.var_color) {
let variantColor = all.var_color.color.primary;
console.log(variantColor);
}
}

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;
}, []);

Get last deepest level item in object

I have data and function like this:
const lodash = require('lodash')
var data = [
{
"nextStep": [
{
"nextStep": [
{
"nextStep": [
{
"nextStep": [],
"student": {
"name": "Alice",
"grade": 1
}
}
],
"student": {
"name": "Lisa",
"grade": 2
}
}
],
"student": {
"grade": 3,
"name": "This is GS"
}
}
],
"student": {
"grade": 4,
"name": "Paul"
}
}
]
function searchByJsonPath(path, obj, target) {
for (var k in obj) {
if (obj.hasOwnProperty(k))
if (k === target)
return path;
else if (typeof obj[k] === "object") {
var result = searchByJsonPath(path + "." + k, obj[k], target);
if (result)
return result;
}
}
return false;
}
I want to get the last item in object, the result should be
"name": "Alice",
"grade": 1
So I call the searchByJsonPath to get the path and use the lodash to get an item
test = searchByJsonPath('data', data, 'name');
but test = data.0.nextStep.0.nextStep.0.nextStep.0.student
the correct path should be data[0].nextStep[0].nextStep[0].nextStep[0].student
Please advice me.
You can try recursion like below to get the deepest element
var data = [{ "nextStep": [ { "nextStep": [ { "nextStep": [ { "nextStep": [], "student": { "name": "Alice", "grade": 1 } } ], "student": { "name": "Lisa", "grade": 2 } } ], "student": { "grade": 3, "name": "This is GS" } } ], "student": { "grade": 4, "name": "Paul" }}]
function getData(obj) {
return obj.nextStep.length > 0
? getData(obj.nextStep[0])
: obj.student
}
console.log(getData(data[0]))

Javascript create 2 arrays from object data

I have some data and I need a loop which creates 2 arrays...
So I first create the 2 arrays:
namelist = [];
countList = [];
{
"id": "622",
"name": "main",
"sub": {
"637": {
"id": "637",
"name": "name 1",
"stats": {
"count": 5
}
},
"638": {
"id": "638",
"name": "name 2",
"stats": {
"count": 10
}
}
}
}
The desired result for this example would be:
For namelist:
['name 1', 'name 2']
For countList:
[5, 10]
How can I do this?
var nameList = [];
var countList = [];
var myObj =
{
"id": "622",
"name": "main",
"sub": {
"637": {
"id": "637",
"name": "name 1",
"stats": {
"count": 5
}
},
"638": {
"id": "638",
"name": "name 2",
"stats": {
"count": 10
}
}
}
};
for(var key in myObj.sub){
nameList.push(myObj.sub[key].name);
countList.push(myObj.sub[key].stats.count);
}
console.log(nameList);
console.log(countList);
for(var key in obj.sub){
nameList.push(obj.sub[key].name);
countList.push(obj.sub[key].stats.count;
}
Object.keys may help you to walk through object properties. Example related to your object:
var namelist = [],
countList = [],
obj = {
"id": "622",
"name": "main",
"sub": {
"637": {
"id": "637",
"name": "name 1",
"stats": {
"count": 5
}
},
"638": {
"id": "638",
"name": "name 2",
"stats": {
"count": 10
}
}
}
};
Object.keys(obj.sub).forEach(function(item) {
namelist.push(obj.sub[item].name);
countList.push(obj.sub[item].stats.count);
});
console.log(namelist, countList);
Working example: https://jsfiddle.net/ry0zqweL/
Obviously, you can optimise it in many ways. It's just illustrating one of the many solutions.

Categories