Home > database >  Convert objects in nested array of objects
Convert objects in nested array of objects

Time:09-30

I'm having a data structure that looks like this:

[
  [
    { word: "china", count: 0 },
    { word: "kids", count: 1 },
    { word: "music", count: 0 },
  ],
  [
    { word: "china", count: 3 },
    { word: "kids", count: 0 },
    { word: "music", count: 2 },
  ],
  [
    { word: "china", count: 10 },
    { word: "kids", count: 3 },
    { word: "music", count: 2 },
  ]
];

I want to calculate the minimum and maximum number of counts for each value of the property word in the nested array.

For example, the maximum counts for the word "china" is 10 and the minimum is 0.

I would like to accomplish something like this:

{ word: "china", min: 0, max: 10 }

How do I do this?

CodePudding user response:

You can use Array#reduce to collect the minimum and maximum values for a given word while looping over the array.

let arr=[[{word:"china",count:0},{word:"kids",count:1},{word:"music",count:0},],[{word:"china",count:3},{word:"kids",count:0},{word:"music",count:2},],[{word:"china",count:10},{word:"kids",count:3},{word:"music",count:2},]];
const getStats = (arr, w) => arr.flat().reduce((acc, {word, count})=>{
  if (w === word) acc.min = Math.min(acc.min, count), 
      acc.max = Math.max(acc.max, count);
  return acc;
}, { word : w, min: Infinity, max: -Infinity});
console.log(getStats(arr, 'china'));

CodePudding user response:

There are lots of ways to solve this. If you first transform the data into an object whose keys are the words and whose values are the counts of each word, then you can perform any number of operations on the counts (not just finding min and max):

function transform (array) {
  const counts = {};

  for (const {count, word} of array.flat()) {
    (counts[word] ??= []).push(count);
  }

  return counts;
}

const input = [
  [
    { word: "china", count: 0 },
    { word: "kids", count: 1 },
    { word: "music", count: 0 },
  ],
  [
    { word: "china", count: 3 },
    { word: "kids", count: 0 },
    { word: "music", count: 2 },
  ],
  [
    { word: "china", count: 10 },
    { word: "kids", count: 3 },
    { word: "music", count: 2 },
  ],
];

const transformed = transform(input);
console.log(transformed);
//=> { china: [ 0, 3, 10 ], kids: [ 1, 0, 3 ], music: [ 0, 2, 2 ] }

for (const [word, counts] of Object.entries(transformed)) {
  const sorted = [...counts].sort((a, b) => a - b);

  console.log({
    word,
    min: sorted.at(0),
    max: sorted.at(-1),
  });
}
//=>
// { word: "china", min: 0, max: 10 }
// { word: "kids", min: 0, max: 3 }
// { word: "music", min: 0, max: 2 }

Ref:

  • Related