moys
moys

Reputation: 8033

Find all values of a particular key in a array of objects or object of objets

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

Answers (2)

Terry Lennox
Terry Lennox

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

Tobias S.
Tobias S.

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

Related Questions