0

I have an objects array:

[{description: a, category: a},{description: b, category: b},{description: c, category: c}...]

I need to restructure it to this format:

[{category: a, items: [a, b, c, d], priority: 1},{category: b, items: [a, b, c, d], priority: 2},{category: c, items: [a, b, c, d], priority: 10}]

What I did below works and returns the desired result, I'm just wondering if there is a way to shorten it.

const getNewList = items => {
// Filter items to get all categories and set their priority
  let categories: any = [
    ...new Set(
      items.map(item => {
        switch (item.category.toLowerCase()) {
          case 'a':
            return {category: item.category, priority: 1}
          case 'b':
            return {category: item.category, priority: 2}
          case 'c':
            return {category: item.category, priority: 10}
        }
      })
    )
  ]

// Remove duplicate entries
  categories = [
    ...new Map(categories.map(item => [item.category, item])).values()
  ]

// Restructure object - get all items and the priority grouped by category
  const newList = []
  for (var i = 0; i < categories.length; i++) {
    newList.push({
      category: categories[i],
      items: items
        .filter(item=> item.category === categories[i].category)
        .map(item=> {
          return item.description
        }),
      priority: categories[i].priority
    })
  }
  return newList
}
5
  • 1
    Whenever you find yourself creating a new array and pushing items to it, you probably can just use map to create the new array. Commented Sep 13, 2020 at 21:57
  • Is it true that you know the category to priority mapping before you run through this? that is.. it's always { a: 1, b:2, c:10, d: 100 } ( or whatever )? Commented Sep 13, 2020 at 21:58
  • @mrrogers, yes, I know the priority for each category before I run through it Commented Sep 13, 2020 at 21:59
  • So each entry in the result is basically a list of descriptions that match the category? in your example, i think i'm confused because it seems like the use of a,b,c,d might be a bit overloaded. Commented Sep 13, 2020 at 22:09
  • Uncaught SyntaxError: unexpected token: ':' on let categories: any = [ Commented Sep 13, 2020 at 22:10

1 Answer 1

2

You might be looking for

function getNewList(items) {
  const categories = new Map([
    ['a', {category: 'a', items: [], priority: 1}],
    ['b', {category: 'b', items: [], priority: 2}],
    ['c', {category: 'c', items: [], priority: 10}],
  ]);
  for (const item of items) {
    categories.get(item.category.toLowerCase()).items.push(item.description);
  }
  return Array.from(categories.values());
}

If you don't want to have empty categories, you can .filter(c => c.items.length) them out.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.