Home > Software engineering >  Refactor Javascript Object Traversal
Refactor Javascript Object Traversal

Time:03-22

The code that I have does result in the desired output. However, in my opinion, using these nested for loops is a little ugly and I am trying to refactor my work.

My question is: do you have any suggestions on refactoring the code so that I can avoid the need of using these nested for loops?

I want to loop over a nested object and end up with a result of all unique keys, and an array of all values for that unique key.

{"ABC":["1","100","6"],"DEF":["10","2","5"],"GHI":["14","9"],"HGI":["4"]} 

const data = {
  something: [
    {
      innerSomething: {
        list: [
          {
            title: "ABC",
            amount: "1"
          },
          {
            title: "DEF",
            amount: "10"
          },
          {
            title: "GHI",
            amount: "14"
          }
        ],
      }
    },
    {
      innerSomething: {
        list: [
          {
            title: "ABC",
            amount: "100"
          },
          {
            title: "DEF",
            amount: "2"
          },
          {
            title: "GHI",
            amount: "9"
          }
        ],
      }
    },
    {
      innerSomething: {
        list: [
          {
            title: "ABC",
            amount: "6"
          },
          {
            title: "DEF",
            amount: "5"
          },
          {
            title: "HGI",
            amount: "4"
          }
        ],
      }
    }
  ]
};


const results = {};
data.something.forEach((item) => {
  item.innerSomething.list.forEach((list) => {
    if (results[list.title]) {
      // exists already, just push the amount
      results[list.title].push(list.amount)
    } else {
      // Is unique so far, add it to the object
      results[list.title] = [list.amount];
   }
  })
});

console.log(`results: ${JSON.stringify(results)}`);
// These results are the correct and desired output
// {"ABC":["1","100","6"],"DEF":["10","2","5"],"GHI":["14","9"],"HGI":["4"]}

CodePudding user response:

Your implementation is ok, tbh. The only thing I can suggest differently is to make use of the neat destructuring patterns and spread syntax, considering that the structure of your input object is very well known:

data.something.forEach(({ innerSomething: { list } }) =>
  list.forEach(({ title, amount }) => 
    results[title] = [...results[title] || [], amount]))

CodePudding user response:

For what it's worth, here is how I'd write it.

const data = {
  something: [
    {
      innerSomething: {
        list: [
          {
            title: "ABC",
            amount: "1"
          },
          {
            title: "DEF",
            amount: "10"
          },
          {
            title: "GHI",
            amount: "14"
          }
        ],
      }
    },
    {
      innerSomething: {
        list: [
          {
            title: "ABC",
            amount: "100"
          },
          {
            title: "DEF",
            amount: "2"
          },
          {
            title: "GHI",
            amount: "9"
          }
        ],
      }
    },
    {
      innerSomething: {
        list: [
          {
            title: "ABC",
            amount: "6"
          },
          {
            title: "DEF",
            amount: "5"
          },
          {
            title: "GHI",
            amount: "4"
          }
        ],
      }
    }
  ]
};

const results = {};
for (let something of data.something) {
  for (let item of something.innerSomething.list) {
    const { title, amount } = item;
    results[title] = results[title] || [];
    results[title].push(amount);
  }
}

console.log(`results: ${JSON.stringify(results)}`);

  • Related