0

I have an array of objects (groceryArray) that I would like to organize into an object by the groupId property (object keys) and finally sort these keys by the groupDisplayOrder property. See finalOutput for desired result.

const groceryArray = [
    { id: 'apples', groupId: 'produce', groupDisplayOrder: 1 },
    { id: 'chicken', groupId: 'meat', groupDisplayOrder: 3 },
    { id: 'shrimp', groupId: 'seafood', groupDisplayOrder: 4 },
    { id: 'milk', groupId: 'dairy', groupDisplayOrder: 2 },
    { id: 'carrots', groupId: 'produce', groupDisplayOrder: 1 },
    { id: 'salmon', groupId: 'seafood', groupDisplayOrder: 4 }
]

Desired Result

const finalOutput = {
    produce: [{ id: 'apples', groupId: 'produce', groupDisplayOrder: 1 }, { id: 'carrots', groupId: 'produce', groupDisplayOrder: 1 }],
    dairy: [{ id: 'milk', groupId: 'dairy', groupDisplayOrder: 2 }],
    meat: [{ id: 'chicken', groupId: 'meat', groupDisplayOrder: 3 }],
    seafood: [{ id: 'shrimp', groupId: 'seafood', groupDisplayOrder: 4 }, { id: 'salmon', groupId: 'seafood', groupDisplayOrder: 4 }]
}

Here's my current code ... I think I may be doing too many steps. I'm wondering if there is a way to reduce and sort at the same time?

  const groceriesGroupedById = groceryArray.reduce((acc, cur) => {
    if (cur.groupId) {
      (acc[cur.groupId] || (acc[cur.groupId] = [])).push(cur)
    }
    return acc
  }, {})

  const sortedGroupIds = Object.keys(groceriesGroupedById).sort((a, b) => {
    return groceriesGroupedById[a][0].groupDisplayOrder - groceriesGroupedById[b][0].groupDisplayOrder
  })

  const finalOutput = sortedGroupIds.reduce((acc, key) => ( acc[key] = groceriesGroupedById[key], acc ), {})
1
  • Who closed this? Can you please reopen... this is different as I am asking to group and sort... Commented May 4, 2021 at 18:08

3 Answers 3

1

First, sort array using Array.sort() and use Array.reduce()

const groceryArray = [
    { id: 'apples', groupId: 'produce', groupDisplayOrder: 1 },
    { id: 'chicken', groupId: 'meat', groupDisplayOrder: 3 },
    { id: 'shrimp', groupId: 'seafood', groupDisplayOrder: 4 },
    { id: 'milk', groupId: 'dairy', groupDisplayOrder: 2 },
    { id: 'carrots', groupId: 'produce', groupDisplayOrder: 1 },
    { id: 'salmon', groupId: 'seafood', groupDisplayOrder: 4 }
];

groceryArray.sort((a, b) => a.groupDisplayOrder - b.groupDisplayOrder);

const finalOutput = groceryArray.reduce((acc, cur) => {
  if (!acc[cur.groupId]) acc[cur.groupId] = [];
  acc[cur.groupId].push(cur);
  return acc;
}, {});

console.log(finalOutput);

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

2 Comments

Thanks! The goal is to also sort the new object keys by groupDisplayOrder ... e.g dairy should be second key.
Thank you! Much simpler than what I had :)
0

You could take a nested approach by using an array and groupDisplayOrder with object with groupId as key.

At the end combine all objects into a single object.

const
    groceryArray = [{ id: 'apples', groupId: 'produce', groupDisplayOrder: 1 }, { id: 'chicken', groupId: 'meat', groupDisplayOrder: 3 }, { id: 'shrimp', groupId: 'seafood', groupDisplayOrder: 4 }, { id: 'milk', groupId: 'dairy', groupDisplayOrder: 2 }, { id: 'carrots', groupId: 'produce', groupDisplayOrder: 1 }, { id: 'salmon', groupId: 'seafood', groupDisplayOrder: 4 }],
    result = Object.assign({}, ...groceryArray.reduce((r, o) => {
        ((r[o.groupDisplayOrder] ??= {})[o.groupId] ??= []).push(o);
        return r;
    }, []));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

0

Using Map and Array#reduce you can group the data and then loop over all the values and sort them.

const 
  groceryArray=[{id:"apples",groupId:"produce",groupDisplayOrder:1},{id:"chicken",groupId:"meat",groupDisplayOrder:3},{id:"shrimp",groupId:"seafood",groupDisplayOrder:4},{id:"milk",groupId:"dairy",groupDisplayOrder:2},{id:"carrots",groupId:"produce",groupDisplayOrder:1},{id:"salmon",groupId:"seafood",groupDisplayOrder:4}],

  res = groceryArray.reduce((r, o) => ((r[o.groupId] ??= []), r[o.groupId].push(o), r), {});

Object.values(res).forEach((o) => o.sort(({ groupDisplayOrder: a }, { groupDisplayOrder: b }) => a - b));

console.log(res);

1 Comment

@Michael Please check if this solves your problem, do let me know if you have any issues.

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.