Home > OS >  Group the parent object array based on the filter of the child object array
Group the parent object array based on the filter of the child object array

Time:10-09

I've coded and I've got the results I want, but I think this code looks unclean.

const verses = [{
    index: 1,
    verses: [{
        level: 1
      },
      {
        level: 1
      }
    ]
  },
  {
    index: 2,
    verses: [{
        level: 1
      },
      {
        level: 1
      }
    ]
  },
  {
    index: 3,
    verses: [{
      level: 2
    }]
  },
  {
    index: 4,
    verses: [{
      level: 2
    }]
  },
  {
    index: 5,
    verses: [{
        level: 2
      },
      {
        level: 2
      }
    ]
  },
  {
    index: 6,
    verses: [{
        level: 3
      },
      {
        level: 3
      }
    ]
  },
  {
    index: 7,
    verses: [{
        level: 3
      },
      {
        level: 3
      },
      {
        level: 4
      },
      {
        level: 4
      }
    ]
  }
]

function getVerseIndexByLevel(level) {
  const result = verses.map(v => {
    const mappingByLevel = Math.max.apply(Math, [...new Set(v.verses.map(w => w.level))])
    const mappingByVerse = v.index

    return {
      level: mappingByLevel,
      verse: mappingByVerse
    }
  }).filter(v => v.level === level).map(v => v.verse)

  return result
}

for (let i = 1; i <= 4; i  ) {
  console.log({
    level: i,
    verse: getVerseIndexByLevel(i)
  })
}

Is my code above consuming too much performance?

Could you make it cleaner and simpler without changing the result at all?

-I don't know what details I have to add more, StackOverflow forced me to write this because the post is mostly code. but I hope you understand just by looking at the results of the code.-

CodePudding user response:

On the performance end, the one thing I can see that could improve it would be to call getVerseIndexByLevel only once, and use the calculated result mapping, instead of calling it multiple times (requiring re-parsing the input every time). Something like

const verseIndicies = getVerseIndicies();
for (let i = 1; i <= 4; i  ) {
  console.log({
    level: i,
    verse: verseIndicies[i]
  })
}

Another slight improvement - since you're using ES6 syntax, you don't need to .apply to Math.max - just spread the set into it.

You also don't need to turn the level numbers into a Set first - since it's being passed into Math.max anyway, repetitions aren't an issue.

const verses=[{index:1,verses:[{level:1},{level:1}]},{index:2,verses:[{level:1},{level:1}]},{index:3,verses:[{level:2}]},{index:4,verses:[{level:2}]},{index:5,verses:[{level:2},{level:2}]},{index:6,verses:[{level:3},{level:3}]},{index:7,verses:[{level:3},{level:3},{level:4},{level:4}]}];

function getVerseIndicies() {
  const verseIndicies = {};
  for (const v of verses) {
      const level = Math.max(...v.verses.map(w => w.level));
      verseIndicies[level] ??= [];
      verseIndicies[level].push(v.index);
  }
  return verseIndicies;
}

const verseIndicies = getVerseIndicies();
for (let i = 1; i <= 4; i  ) {
  console.log({
    level: i,
    verse: verseIndicies[i]
  })
}

  • Related