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:
- search if the song already exists in the accumulator array.
- if so, concat the artist to the list
- 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