Trying to use javascript to sort an array of song names into a nested array with matching artists. In the code below there is are sample arrays to show you can example of what is happening. For some reason for some of the nested arrays the first song does not get pushed to it. Not sure why. I think it has something to do with the artistIndex
but I'm not sure how to fix it. This is the console output:
artistIndex = 0
tempPlaylist = [
'1 - a',
'2 - a',
'2 - a',
'3 - a',
'3 - b',
'3 - c',
'4 - a',
'5 - a',
'5 - b',
'6 - a',
]
artistsNested = [
['1'],
['2'],
['3'],
['4'],
['5'],
['6'],
]
for (let song of tempPlaylist) {
artistSongSplit = song.split(' - ');
artistName = artistSongSplit[0];
songName = artistSongSplit[1];
if (artistName.toUpperCase() === artistsNested[artistIndex][0].toUpperCase()) {
artistSongSplit = song.split(' - ');
artistsNested[artistIndex].push(songName)
} else if (artistName.toUpperCase() != artistsNested[artistIndex][0].toUpperCase()) {
artistIndex = 1
}
}
console.log(artistsNested)
CodePudding user response:
You can simplify this a little by creating an intermediate Map keyed by the artist name. It's then just a matter of accessing the relevant 'artist' in the map and pushing each 'song' to the referenced array.
const tempPlaylist = ['1 - a', '2 - a', '2 - a', '3 - a', '3 - b', '3 - c', '4 - a', '5 - a', '5 - b', '6 - a'];
const artistsNested = [['1'], ['2'], ['3'], ['4'], ['5'], ['6']];
const map = new Map(artistsNested.map(([a]) => [a.toUpperCase(), [a]]));
for (const track of tempPlaylist) {
const [artist, song] = track.split('-').map((s) => s.trim());
if (map.has(artist.toUpperCase())) {
map.get(artist.toUpperCase()).push(song);
}
}
const result = [...map.values()];
console.log(result);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
The above snippet desctructures the artist name in creating the Map and creates new sub-arrays for each so as not to overwrite the artistsNested
array, but if you did want to mutate it in place you can simply maintain references to the original nested arrays.
const tempPlaylist = ['1 - a', '2 - a', '2 - a', '3 - a', '3 - b', '3 - c', '4 - a', '5 - a', '5 - b', '6 - a'];
const artistsNested = [['1'], ['2'], ['3'], ['4'], ['5'], ['6']];
// keep references to original nested arrays in Map
let map = new Map(artistsNested.map((a) => [a[0].toUpperCase(), a]));
for (const track of tempPlaylist) {
const [artist, song] = track.split('-').map((s) => s.trim());
if (map.has(artist.toUpperCase())) {
map.get(artist.toUpperCase()).push(song);
}
}
// pushes to the nested arrays in place
console.log(artistsNested);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Alternatively, to mutate the artistsNested array in place without the intermediate lookup table you can use find()
to find the relevant 'artist' sub-array and push to it if it exists.
const tempPlaylist = ['1 - a', '2 - a', '2 - a', '3 - a', '3 - b', '3 - c', '4 - a', '5 - a', '5 - b', '6 - a'];
const artistsNested = [['1'], ['2'], ['3'], ['4'], ['5'], ['6']];
for (const track of tempPlaylist) {
const [artist, song] = track.split('-').map((s) => s.trim());
const artistList = artistsNested.find((artist_arr) =>
artist_arr[0].toUpperCase() === artist.toUpperCase());
if (artistList !== undefined) {
artistList.push(song);
}
}
console.log(artistsNested);
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>