Reputation: 8033
I have an array of objects as below
let arr = [
{
name: "string 1",
details: [
{
id: 1,
values: [
{ date: "12-Mar", score: "15" },
{ date: "13-Mar", score: "16" },
{ date: "14-Mar", score: "17" },
{ date: "15-Mar", score: "18" },
],
},
],
},
{
name: "string 2",
details: [
{
id: 2,
values: [
{ date: "12-Mar", score: "16" },
{ date: "13-Mar", score: "17" },
{ date: "14-Mar", score: "18" },
{ date: "15-Mar", score: "19" },
],
},
],
},
{
name: "string 3",
details: [
{
id: 2,
values: [
{ date: "12-Mar", score: "21" },
{ date: "13-Mar", score: "22" },
{ date: "14-Mar", score: "23" },
{ date: "15-Mar", score: "24" },
],
},
],
},
];
I also have the same data as an object of objects as below
let obj = {
"string 1": {
details: [
{
id: 1,
values: [
{ date: "12-Mar", score: "15" },
{ date: "13-Mar", score: "16" },
{ date: "14-Mar", score: "17" },
{ date: "15-Mar", score: "18" },
],
},
],
},
"string 2": {
details: [
{
id: 2,
values: [
{ date: "12-Mar", score: "16" },
{ date: "13-Mar", score: "17" },
{ date: "14-Mar", score: "18" },
{ date: "15-Mar", score: "19" },
],
},
],
},
"string 3": {
details: [
{
id: "2",
values: [
{ date: "12-Mar", score: "21" },
{ date: "13-Mar", score: "22" },
{ date: "14-Mar", score: "23" },
{ date: "15-Mar", score: "24" },
],
},
],
},
};
I want to find all the dates & all the scores as an array. For the array of ojects, with the help of answer here (How to find all values of a specific key in an array of nested objects?), I was able to get the result with the code below.
Since I did not want the dates to be repeated, I created a Set
dates = new Set(getValue(arr, "date"))
However, for the object of objects, I am not able to get the results. How do I go about it.
Also, I have the option to get my data as an array
of objects or an object
of objects. Since I have to perform a lot of manipulation/analysis (I will be using this with D3 library t build charts), which is the better format? Can anyone guide? Thanks.
Upvotes: 1
Views: 101
Reputation: 30675
You could use a recursive approach (as in the referenced answer) to pick all properties for a given key. One can also add a unique
parameter, if this is set to true we'll create a Set from the properties to ensure we don't return any duplicates:
let arr = [ { name: "string 1", details: [ { id: 1, values: [ { date: "12-Mar", score: "15" }, { date: "13-Mar", score: "16" }, { date: "14-Mar", score: "17" }, { date: "15-Mar", score: "18" }, ], }, ], }, { name: "string 2", details: [ { id: 2, values: [ { date: "12-Mar", score: "16" }, { date: "13-Mar", score: "17" }, { date: "14-Mar", score: "18" }, { date: "15-Mar", score: "19" }, ], }, ], }, { name: "string 3", details: [ { id: 2, values: [ { date: "12-Mar", score: "21" }, { date: "13-Mar", score: "22" }, { date: "14-Mar", score: "23" }, { date: "15-Mar", score: "24" }, ], }, ], }, ];
let obj = { "string 1": { details: [ { id: 1, values: [ { date: "12-Mar", score: "15" }, { date: "13-Mar", score: "16" }, { date: "14-Mar", score: "17" }, { date: "15-Mar", score: "18" }, ], }, ], }, "string 2": { details: [ { id: 2, values: [ { date: "12-Mar", score: "16" }, { date: "13-Mar", score: "17" }, { date: "14-Mar", score: "18" }, { date: "15-Mar", score: "19" }, ], }, ], }, "string 3": { details: [ { id: "2", values: [ { date: "12-Mar", score: "21" }, { date: "13-Mar", score: "22" }, { date: "14-Mar", score: "23" }, { date: "15-Mar", score: "24" }, ], }, ], }, };
function getProperties(obj, key, unique = true, result = []) {
for(let k in obj) {
if (typeof(obj[k]) === 'object') {
getProperties(obj[k], key, unique, result);
} else if (k === key) {
result.push(obj[k]);
}
}
return unique ? [...new Set(result)]: result;
}
console.log('Dates (arr):', JSON.stringify(getProperties(arr, 'date', true)))
console.log('Scores (arr):', JSON.stringify(getProperties(arr, 'score', true)))
console.log('Dates (obj):', JSON.stringify(getProperties(obj, 'date', true)))
console.log('Scores (obj):', JSON.stringify(getProperties(obj, 'score', true)))
Upvotes: 1
Reputation: 23825
You can iterate over the top-level keys in your object like this:
for (let key in obj){
let val = obj[key]
/* From here you can proceed with finding all values
like you did with the array
*/
}
Upvotes: 1