Trying to 'map' nested JSON element object (javascript) - javascript

I am trying to 'map' nested JSON elements that have objects in order to build HTML. I am not sure what I am doing wrong with the syntax as follows:
array1 = [
{
"name":"test",
"things": [
{ "name":"thing1" },
{ "name": "thing2"}
]
}
];
const createThingy = (item) => `
<p>${item.name}</p>
`
// pass a function to map
const map1 = array1.things.map(createThingy).join('');
console.log(array1);
// expected output: <p>thing1</p><p>thing2</p>
Thank you in advance for your time and consideration.

Think of the array as an object. It's accessed in a similar way, so if it were an object it would be like this:
let array1 = {
0: {
"name":"test",
"things": [
{ "name": "thing1" },
{ "name": "thing2" }
]
}
};
Therefore, to access its first element directly you need:
array1[0].things
To get your desired outcome you need to the following:
let array1 = [
{
"name": "test",
"things": [
{ "name": "thing1" },
{ "name": "thing2" }
]
}
];
const createThingy = (item) => `
<p>${item.name}</p>
`;
// pass a function to map
const map1 = array1[0].things.map(createThingy).join('');
console.log(map1);
In case your array can have multiple elements, you can use the following:
let array1 = [
{
"name": "test",
"things": [
{ "name": "thing1" },
{ "name": "thing2" }
]
}
];
const createThingy = (item) => `
<p>${item.name}</p>
`;
// pass a function to map
const map1 = array1.reduce((acc, elem) => acc + elem.things.map(createThingy).join(''), "");
console.log(map1);

array1 = [
{
"name":"test",
"things": [
{ "name":"thing1" },
{ "name": "thing2"}
]
}
];
const createThingy = (item) => `
<p>${item.name}</p>
`
// pass a function to map
const map1 = array1[0].things.map(createThingy).join('');
console.log(array1);
console.log(map1);

As Nick Parsons said, you have to loop over the array1 array to get things property.
const array1 = [
{
"name":"test",
"things": [
{ "name":"thing1" },
{ "name": "thing2"}
]
}
];
const createThingy = (item) => `
<p>${item.name}</p>
`
// pass a function to map
const map1 = array1[0].things.map(createThingy).join('');
console.log(array1);
console.log(map1);
Also, be advised that if your array1 variable is empty or in case there is no things attribute in preferred index, your code code will give error. Be sure to check if they are empty. You can do this by using lodash isEmpty function.

You have to loop over the array1 to get the desired output as Nick Parsons said in the comments.
array1 = [
{
"name":"test",
"things": [
{ "name":"thing1" },
{ "name": "thing2"}
]
}
];
const createThingy = (item) => `
<p>${item.name}</p>
`
array1.map(item => {
item.map(key => createThingy(key).join(''));
});
// expected output: <p>thing1</p><p>thing2</p>

Related

Combine children where parent keys are the same in a array of objects

I have an array of objects with duplicate parent keys:
[
{parent1: {'child_id_1': 'value_child_1'}}
{parent1: {'child_id_1_1': 'value_child_1_1'}}
{parent2: {'child_id_2_1': 'value_child_2_1'}}
{parent2: {'child_id_2_2': 'value_child_2_2'}}
{parent2: {'child_id_2_3': 'value_child_2_3'}}
...
]
And I'm looking for this result:
[
{parent1: {'child_id_1': 'value_child_1'}, {'child_id_1_1': 'value_child_1_1'}}
{parent2: {'child_id_2_1': 'value_child_2_1'}, {'child_id_2_2': 'value_child_2_2'}, {'child_id_2_3': 'value_child_2_3'}}
]
I've tried something similar to this below but it only returns one key pair.
const unique = Array.from(new Set(filteredViews.map(a => a.id)))
.map(id => {
return filteredViews.find(a => a.view_name === id)
})
Any help would be greatly appreciated!
Assuming your data looks like this:
const data = [
{parent1: {'child_id_1': 'value_child_1'}},
{parent1: {'child_id_1_1': 'value_child_1_1'}},
{parent2: {'child_id_2_1': 'value_child_2_1'}},
{parent2: {'child_id_2_2': 'value_child_2_2'}},
{parent2: {'child_id_2_3': 'value_child_2_3'}},
]
Using a vanilla approach you could do:
let unique = {};
data.forEach(d => {
let key = Object.keys(d)[0]; // assuming your object has a single key
if (!unique[key]) { unique[key] = []; }
unique[key].push(d[key]);
});
Resulting in:
{
"parent1": [
{"child_id_1":"value_child_1"},
{"child_id_1_1":"value_child_1_1"}
],
"parent2": [
{"child_id_2_1":"value_child_2_1"},
{"child_id_2_2":"value_child_2_2"},
{"child_id_2_3":"value_child_2_3"}
]
}
Using Array.prototype.reduce:
const srcArr = [
{parent1: {'child_id_1': 'value_child_1'}},
{parent1: {'child_id_1_1': 'value_child_1_1'}},
{parent2: {'child_id_2_1': 'value_child_2_1'}},
{parent2: {'child_id_2_2': 'value_child_2_2'}},
{parent2: {'child_id_2_3': 'value_child_2_3'}},
];
const targetArr = srcArr.reduce((acc, val) => {
let [key] = Object.keys(val);
let obj = acc.find(el => key in el);
if (!obj) acc.push({[key]: [val[key]]});
else obj[key].push(val[key]);
return acc;
}, []);
console.log(targetArr);
/* result:
[
{
"parent1": [
{
"child_id_1": "value_child_1"
},
{
"child_id_1_1": "value_child_1_1"
}
]
},
{
"parent2": [
{
"child_id_2_1": "value_child_2_1"
},
{
"child_id_2_2": "value_child_2_2"
},
{
"child_id_2_3": "value_child_2_3"
}
]
}
]
*/

How to format values of the arrays of array as required?

I have the following array which includes arrays of objects.
const arr = [
[
{
"key1": "keyName",
"key2": "test name1"
},
{
"key1": "keyDescription",
"key2": "test description1"
}
],
[
{
"key1": "keyName",
"key2": "test name2"
},
{
"key1": "keyDescription",
"key2": "test description2"
}
]
]
The result which I required is as follows.
result = [
{
"key_name": "test name1",
"key_description": "test description1"
},
{
"key_name": "test name2",
"key_description": "test description2"
}
]
I have tried this using js 'map' and 'find' methods and it gived wrong format.
const res = arr.map(i => i.find(j => j.setting_code === "hotelRate")).map(k => k.setting_value)
I heard that this can be done using 'reduce'. I would be grateful for suggestions. Thanks!
The following solution just uses map and then a forEach loop inside that map to add the [key1]: key2 object pair to each object.
const arr=[[{key1:"keyName",key2:"test name1"},{key1:"keyDescription",key2:"test description1"}],[{key1:"keyName",key2:"test name2"},{key1:"keyDescription",key2:"test description2"}]];
const result = arr.map(el => {
const obj = {};
el.forEach(({key1, key2}) => {
const snakeKey = key1.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
obj[snakeKey] = key2;
})
return obj;
})
console.log(result);
Edit: As Andreas points out in the comments, this can be written with a reduce method if that is a requirement:
const result = arr.map(el => {
return el.reduce((result, current) => {
const snakeKey = current.key1.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
result[snakeKey] = current.key2;
return result;
}, {});
})
arr.map(function(item) {
var props = {};
item.forEach(function(keyValue) {
props[keyValue["key1"]] = keyValue["key2"];
});
return props;
});

How to map through array merge getting the same for each result [lodash]

I’m trying to merge lessons with user progress data. I believe I have a pointer issue.
I've had success with the inner merge of the two arrays. The issue comes with looping through users and not getting the right lesson data with the progress data attached.
lessons data
let lessons = [
{“id”: “0106c568-70c0-4e56-8139-8e7f7d124f95",},
{“id”: “033e18a2-d470-4fd7-8bdc-53e610f3f784",},
{“id”: “d60f751c-d7d2-4dc6-9eda-a03bc5ebddc6",},
];
all users’ progresses
const usersProgresses = [
[
{
“id”: “cjrtmj9d601b908559oxe8hwk”,
“lesson”: “0106c568-70c0-4e56-8139-8e7f7d124f95",
“score”: null,
},
{
“id”: “cjrtmk2hv01bx0855yof2ehj4”,
“lesson”: “033e18a2-d470-4fd7-8bdc-53e610f3f784”,
“score”: 100,
},
{
“id”: “cjrtmlohd01cp0855jnzladye”,
“lesson”: “3724d7df-311c-46d9-934f-a9c44d9335ae”,
“score”: 20,
}
],
...
];
loop through users and merge progresses in lessons
// for each user
const result = usersProgresses.map(user => {
// merge progress and lesson data by lesson.id
const mergedProgress = [...lessons].map(lesson => {
return _.merge(lesson,_ .find(userProgress, { lesson: lesson.id }));
});
return mergedProgress;
});
Expected data out of result:
[
[
{
“id”: “0106c568-70c0-4e56-8139-8e7f7d124f95”,
“lesson”: “0106c568-70c0-4e56-8139-8e7f7d124f95”,
“score”: null,
},
{
“id”: “033e18a2-d470-4fd7-8bdc-53e610f3f784",
“lesson”: “033e18a2-d470-4fd7-8bdc-53e610f3f784",
“score”: 100,
},
{
“id”: “d60f751c-d7d2-4dc6-9eda-a03bc5ebddc6”,
}
]
]
but getting:
[
[
{
“id”: “0106c568-70c0-4e56-8139-8e7f7d124f95”,
},
{
“id”: “033e18a2-d470-4fd7-8bdc-53e610f3f784”,
},
{
“id”: “d60f751c-d7d2-4dc6-9eda-a03bc5ebddc6”,
}
]
]
You could do something like this using a nested .map in vanilla js:
const lessons = [{"id":"0106c568-70c0-4e56-8139-8e7f7d124f95",},{"id":"033e18a2-d470-4fd7-8bdc-53e610f3f784",},{"id":"d60f751c-d7d2-4dc6-9eda-a03bc5ebddc6",}]
const usersProgress = [[{"id":"cjrtmj9d601b908559oxe8hwk","lesson":"0106c568-70c0-4e56-8139-8e7f7d124f95","score":null,},{"id":"cjrtmk2hv01bx0855yof2ehj4","lesson":"033e18a2-d470-4fd7-8bdc-53e610f3f784","score":100,},{"id":"cjrtmlohd01cp0855jnzladye","lesson":"3724d7df-311c-46d9-934f-a9c44d9335ae","score":20,}]]
const output = usersProgress.map(user => lessons.map(lesson =>
({...user.find(p => p.lesson == lesson.id), ...lesson }))
);
console.log(output)
You can use _.keyBy() to create a dictionary of user lessons by lesson id. When creating the result object, get the lesson by the id using brackets notation, and spread it (undefined values would be ignored).
const lessons = [{"id":"0106c568-70c0-4e56-8139-8e7f7d124f95",},{"id":"033e18a2-d470-4fd7-8bdc-53e610f3f784",},{"id":"d60f751c-d7d2-4dc6-9eda-a03bc5ebddc6",}]
const usersProgress = [[{"id":"cjrtmj9d601b908559oxe8hwk","lesson":"0106c568-70c0-4e56-8139-8e7f7d124f95","score":null,},{"id":"cjrtmk2hv01bx0855yof2ehj4","lesson":"033e18a2-d470-4fd7-8bdc-53e610f3f784","score":100,},{"id":"cjrtmlohd01cp0855jnzladye","lesson":"3724d7df-311c-46d9-934f-a9c44d9335ae","score":20,}]]
const result = usersProgress.map(user => {
const lessonsById = _.keyBy(user, 'lesson') // create a dictionary of lesson by id
return lessons.map(({ id }) => ({
...lessonsById[id], // get the lesson or undefined if not found, and spread
id
}))
});
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
const usersProgresses = [
[
{
"id": "cjrtmj9d601b908559oxe8hwk",
"lesson": "0106c568-70c0-4e56-8139-8e7f7d124f95",
"score": null,
},
{
"id": "cjrtmk2hv01bx0855yof2ehj4",
"lesson": "033e18a2-d470-4fd7-8bdc-53e610f3f784",
"score": 100,
},
{
"id": "cjrtmlohd01cp0855jnzladye",
"lesson": "3724d7df-311c-46d9-934f-a9c44d9335ae",
"score": 20,
}
],
];
let lessons = [
{"id": "0106c568-70c0-4e56-8139-8e7f7d124f95",},
{"id": "033e18a2-d470-4fd7-8bdc-53e610f3f784",},
{"id": "d60f751c-d7d2-4dc6-9eda-a03bc5ebddc6",},
];
const mergedProgress = usersProgresses.map((Progresses) => {
return [...lessons].map(lesson => {
return Object.assign(lesson, Progresses.find((i) => i.lesson === lesson.id));
});
})
console.log(mergedProgress)

Merge two json arrays

I have to array i want to merge them in one array by same id. So every two array have same id should be merged
Case 1:
{
"id":1212,
"instructor":"william",
...
}
Case 2:
[
{
"id":1212,
"name":"accounting",
...
},
{
"id":1212,
"name":"finance",
...
}
]
I need the result to be :
{
"id": 1212,
"instructor": "william",
"Courses": [
{
"id":1212,
"name":"accounting",
...
},
{
"id":1212,
"name":"finance",
...
}
]
}
What you're asking isn't merging, but here is how you can do that.
const instructors = [{ "id":1212, "instructor":"william", }];
const courses = [
{ "id":1212, "name":"accounting" },
{ "id":1212, "name":"finance" }
];
const expected = [{ "id":1212, "instructor":"william", "courses": [
{ "id":1212, "name":"accounting" },
{ "id":1212, "name":"finance" }
]}];
const composed = instructors.map(ins => {
const ret = {...ins};
ret.courses = courses.filter(cou => cou.id === ins.id);
return ret;
});
console.log(composed);
var finArr;
var course = [];
use forEach loop javascript get all value in put your value instead of varid and varname
course.push({"id":varid,"name":varname});
finArr = {"id":variableId,"instructor":variablename,"Courses":course}

Destructuring array of objects in es6

In es6, how can i simplify the following lines using destructuring?:
const array0 = someArray[0].data;
const array1 = someArray[1].data;
const array2 = someArray[2].data;
Whether using destructuring would actually be a simplification is debatable but this is how it can be done:
const [
{ data: array0 },
{ data: array1 },
{ data: array2 }
] = someArray
Live Example:
const someArray = [
{ data: 1 },
{ data: 2 },
{ data: 3 }
];
const [
{ data: array0 },
{ data: array1 },
{ data: array2 }
] = someArray
console.log(array0, array1, array2);
What is happening is that you're first extracting each object from someArray then destructuring each object by extracting the data property and renaming it:
// these 2 destructuring steps
const [ obj1, obj2, obj3 ] = someArray // step 1
const { data: array0 } = obj1 // step 2
const { data: array1 } = obj2 // step 2
const { data: array2 } = obj3 // step 2
// written together give
const [
{ data: array0 },
{ data: array1 },
{ data: array2 }
] = someArray
Maybe combine destructuring with mapping for (potentially) more readable code:
const [array0, array1, array2] = someArray.map(item => item.data)
Live Example:
const someArray = [
{ data: 1 },
{ data: 2 },
{ data: 3 }
];
const [array0, array1, array2] = someArray.map(item => item.data)
console.log(array0, array1, array2);
I believe what you actually want is
const array = someArray.map(x => x.data)
If you really want three variables (Hint: you shouldn't), you can combine that mapping with destructuring:
const [array0, array1, array2] = someArray.map(x => x.data)
If you want to do with this pure JS then follow this code snippet. It will help you.
let myArray = [
{
"_id": "1",
"subdata": [
{
"subid": "11",
"name": "A"
},
{
"subid": "12",
"name": "B"
}
]
},
{
"_id": "2",
"subdata": [
{
"subid": "12",
"name": "B"
},
{
"subid": "33",
"name": "E"
}
]
}
]
const array = myArray.map(x => x.subdata).flat(1)
const isExist = (key,value, a) => {
return a.find(item => item[key] == value)
}
let a = array.reduce((acc, curr) => {
if(!isExist('subid', curr.subid, acc)) {
acc.push(curr)
}
return acc
}, [])
console.log(a)
const myInfo = someArray.map((item) => {
const {itemval1, itemval2} = item;
return(
//return data how you want it eg:
<p>{itemval1}</p>
<p>{itemval2}</p>)
})
This is how I did it in react, correct me if m wrong, I'm still new to this world
#Daniel, I presume you were looking to destructure a nested Object in an array of Objects. Following #nem035 was able to extract the nested Object's property using his pattern.
What is happening is that you're first extracting each object from addresses array then destructuring each object by extracting its properties and renaming it including the nested Object:
addresses = [
{
locality:"Sarjapura, Bangalore",
coordinates:{latitude:"12.901160", longitude:"77.711680"}
},
{
locality:"Vadakara, Kozhikode",
coordinates:{latitude:"11.588980", longitude:"75.596450"}
}
]
const [
{locality:loc1, coordinates:{latitude:lat1, longitude:ltd1}},
{locality:loc2, coordinates:{latitude:lat2, longitude:ltd2}}
] = addresses
console.log(`Latitude of Vadakara :: ${lat2}`)

Categories