Home > Back-end >  How to merge values of a specific key with repeating objects into one object in an array of JSON obj
How to merge values of a specific key with repeating objects into one object in an array of JSON obj

Time:07-02

I'm working with an array of JSON objects in Angular, which contains JSON objects with are repeated but differ in only one key-value pair, I want to merge the same value objects into one but append the values to the key which has different value:

Original Array:

this.oldArray = [
      {"song_id": 11, "artist_name": "Arijit", "song_name": "Song1"},
      {"song_id": 11, "artist_name" : "Shreya", "song_name": "Song1"},
      {"song_id": 12,"artist_name": "Jason", "song_name": "Song2"},
      {"song_id": 12,"artist_name": "Ankit", "song_name": "Song2"},
      {"song_id": 13,"artist_name": "Asha", "song_name": "Song3"},
      {"song_id": 13,"artist_name": "Lata", "song_name": "Song3"},
      {"song_id": 13,"artist_name": "Bapi", "song_name": "Song3"},
    ]

Desired Array:

this.newArray = [
      {"song_id": 11, "artist_name": "Arijit, Shreya", "song_name": "Song1"},
      {"song_id": 12,"artist_name": "Jason, Ankit", "song_name": "Song2"},
      {"song_id": 13,"artist_name": "Asha, Lata, Bapi", "song_name": "Song3"},
    ]

I tried using reduce, but could not achieve the desired output, kindly help me out!

Thanks

CodePudding user response:

This is one way to implement the reduce function. The principle is the following:

  1. search if the song already exists in the accumulator array.
  2. if so, concat the artist to the list
  3. if not, simply copy the song record in the accumulator array

const oldArray = [
  {"song_id": 11, "artist_name": "Arijit", "song_name": "Song1"},
  {"song_id": 11, "artist_name": "Shreya", "song_name": "Song1"},
  {"song_id": 12, "artist_name": "Jason", "song_name": "Song2"},
  {"song_id": 12, "artist_name": "Ankit", "song_name": "Song2"},
  {"song_id": 13, "artist_name": "Asha", "song_name": "Song3"},
  {"song_id": 13, "artist_name": "Lata", "song_name": "Song3"},
  {"song_id": 13, "artist_name": "Bapi", "song_name": "Song3"}
]

const newArray = oldArray.reduce(
  (acc, song) => {
    const foundIndex = acc.findIndex(({ song_id }) => song_id === song.song_id)
    return foundIndex === -1
      // Song not found, simply add it
      ? [...acc, song]
      // Song is found, edit it with the artist
      : [
        // Copy existing list until the found song
        ...acc.slice(0, foundIndex),
        // edit found song with the new artist
        { ...acc[foundIndex], artist_name: `${acc[foundIndex].artist_name}, ${song.artist_name}` },
        // Copy the rest of the existing list after the found song
        ...acc.slice(foundIndex   1, acc.length)
      ]
  },
  []
)

console.log(newArray)

CodePudding user response:

Use uniq from lodash.

const oldArray = [
  {"song_id": 11, "artist_name": "Arijit", "song_name": "Song1"},
  {"song_id": 11, "artist_name": "Shreya", "song_name": "Song1"},
  {"song_id": 12, "artist_name": "Jason", "song_name": "Song2"},
  {"song_id": 12, "artist_name": "Ankit", "song_name": "Song2"},
  {"song_id": 13, "artist_name": "Asha", "song_name": "Song3"},
  {"song_id": 13, "artist_name": "Lata", "song_name": "Song3"},
  {"song_id": 13, "artist_name": "Bapi", "song_name": "Song3"}
]

const newArray = _.uniq(oldArray, function (e) {
  return e.song_id;
});

console.log(newArray)

Evidence

enter image description here

  • Related