Returning an object using reduce()
PJ Mantoss

PJ Mantoss @pjmantoss

About: I make web apps with HTML/CSS, Javascript, jQuery and ReactJS.

Location:
Abuja, Nigeria
Joined:
Sep 29, 2019

Returning an object using reduce()

Publish Date: Mar 6 '20
3 5

Hi good people! I need help with some JavaScript challenge:

QUESTION: Write a function called getSongCountByArtist which takes in an array of songs and returns an object. The keys in the object should be artist names, and the values should be the number of songs by that artist in the original array.

My code Solution:

function getSongCountByArtist(arr){

return arr.reduce(function(acc,val){
    let artistSong = val.name;
    let songNo = artistSong.length;

    return acc[val.artist] + songNo;

}, {})
Enter fullscreen mode Exit fullscreen mode

}

getSongCountByArtist(songs); //NaN

data source https://github.com/PJMantoss/iterators2/blob/master/data.js

PROBLEM EXPLANATION: The function is supposed to return an object with artist names as keys and number of songs by the artist as values. But On running getSongCountByArtist(songs) it returns NaN. How can I refactor my code to work? Thank you

Comments 5 total

  • EddiFd
    EddiFdMar 6, 2020

    Do not use reduce.

    Try :

    Array.from(new Set(songs.map(e => e.artist).sort()).values()).map(e => {let obj = {}; obj[e] = songs.filter(f => f.artist == e).length; return obj;})

  • Craig McIlwrath
    Craig McIlwrathMar 6, 2020

    You're code is very close, but the function given to reduce should return an object. Instead of returning acc[val.artist] + songNo, you could increment acc[val.artist] by songNo and the return acc.

    Although I'm not sure why you're adding the length of the song name. Maybe just increment by 1 each time?

    • PJ Mantoss
      PJ MantossMar 6, 2020

      Hi Craig! I have applied your suggestion. It's still not returning the right data. It returns an empty object. Please See below:

      function getSongCountByArtist(arr){

      return arr.reduce(function(acc,val){
          let artistName = val.artist,
              artistSong = val.name;
      
           arr[artistName] = artistSong;
      
          if(artistName){
              artistSong += 1;
          }
      
          return acc;
      
      }, {})
      

      }
      //test
      getSongCountByArtist(songs); // {}

      Thank you

      • Craig McIlwrath
        Craig McIlwrathMar 6, 2020

        Seems I didn't describe my idea very well. Here's the code I had in mind:

        function getSongCountByArtist(songs) {
          return songs.reduce(function (acc, song) {
            if (acc[song.artist] === undefined) acc[song.artist] = 0;
            acc[song.artist]++;
            return acc;
          }, {});
        } 
        
        • PJ Mantoss
          PJ MantossMar 7, 2020

          Hello Craig! I've implemented your code and it works perfectly now. Thanks a million! I appreciate your help.

Add comment