0

This might seem a bit weird but I have a need to merge objects in an existing dataset into a new dataset grouped by a specific key value. Here's the dataset:

const object = [
  {
    id: 1,
    scheduledAt: '2022-09-20',
    organization: {
      name: 'Organization 1'
    }
  },
  {
    id: 2,
    scheduledAt: '2022-09-10',
    organization: {
      name: 'Organization 2'
    } 
  },
  {
    id: 3,
    scheduledAt: '2022-09-20',
    organization: {
      name: 'Organization 3'
    }
  }
]

Here is what I am after as the return dataset:

const objectMerged = {
  '2022-09-20': [
    {
      id: 1,
      scheduledAt: '2022-09-20',
      organization: {
        name: 'Organization 1'
      }
    },
    {
      id: 3,
      scheduledAt: '2022-09-20',
      organization: {
        name: 'Organization 3'
      }
    }
  ],
  '2022-09-10': [
    {
      id: 2,
      scheduledAt: '2022-09-10',
      organization: {
        name: 'Organization 2'
      } 
    }
  ]
}

I have tried many different ways but nothing seems to work correctly. Here's the latest code, which does not work:

const merged = []

object.forEach((item) => {
  if (!merged.length) {
    // if the return dataset is empty, add this item immediately
    merged.push({ [item.scheduledAt]: [item] }
  } else {
    // check if item already exists with the same scheduledAt as current object and if so, push it into that array as object
    // if does not exist, create new array entry with the new scheduledAt name

    const find = Object.keys(merged).map((k) => {
      console.log(`key ${k}`)
      console.log(merged[k])
    
      return Object.keys(merged[k]).map((key) => {
        console.log(`key2: ${key}`)
    
        return key === item.scheduledAt
      })
    })

    console.log(find)
  }
})

console.log(merged)

Any help is greatly appreciated. Thank you!

recoilnetworks
  • 488
  • 2
  • 6
  • 21
  • 3
    Does this answer your question? [How can I group an array of objects by key?](https://stackoverflow.com/questions/40774697/how-can-i-group-an-array-of-objects-by-key) – IT goldman Sep 27 '22 at 21:17
  • 1
    `merged` should be an object, not an array. Look at the result you said you want. It's an object. – Barmar Sep 27 '22 at 21:19
  • I'd recommend you to use lodash's [groupBy](https://lodash.com/docs/4.17.15#groupBy) – pavi2410 Sep 27 '22 at 21:27
  • @ITgoldman yes sir, thank you! I spent 6 hours on this last night and another 2 hours today and could not find what I was looking for. Thank you, you are awesome! – recoilnetworks Sep 27 '22 at 21:29
  • @Barmar you are correct, that was my mistake but still did not work however, the other commenter helped me out! – recoilnetworks Sep 27 '22 at 21:30
  • @ITgoldman any idea how to sort this now since it's not an array of objects and instead an object of object arrays? (I think?) – recoilnetworks Sep 27 '22 at 21:34
  • first of all you are awesome for learning. but you can't really sort an object in a reliable way. You can take array of keys using `Object.keys(my_obj).sort()` and then do a `for` loop on that. – IT goldman Sep 27 '22 at 21:35

1 Answers1

0

By using a reduce you can generate what you want. Please have a look:

const object = [
  {
    id: 1,
    scheduledAt: '2022-09-20',
    organization: {
      name: 'Organization 1'
    }
  },
  {
    id: 2,
    scheduledAt: '2022-09-10',
    organization: {
      name: 'Organization 2'
    } 
  },
  {
    id: 3,
    scheduledAt: '2022-09-20',
    organization: {
      name: 'Organization 3'
    }
  },
];

const objectMerged = object
  .sort((objectA, objectB) => 
    objectA.scheduledAt.localeCompare(objectB.scheduledAt)
  )
  .reduce((acc, cur) => ({
    ...acc,
    [cur.scheduledAt]: [
      ...(acc[cur.scheduledAt] || []),
      cur,
    ],
  }), {});

console.log(objectMerged);
dfvc
  • 404
  • 4
  • 6
  • Excellent! Thank you. How would I sort this now by the date? Or, would it make sense to sort the original dataset first? – recoilnetworks Sep 27 '22 at 21:38
  • 1
    You can sort the items before using the reduce, so yes, sort the original dataset first. Edited the snippet, please check. – dfvc Sep 27 '22 at 21:51