skip to Main Content

I feel like this is an easy solve, but I’ve been stuck for a while, so thought I’d reach out for help.

I have an array of objects as per below.

songs = [
{ track_name: "name of track" , track_genres: ["chamber pop","indie pop"] },
{ track_name: "name of track 2" , track_genres: ["dutch r&b","indie soul", "indie pop"] },
{ track_name: "name of track 3" , track_genres: ["indie pop","chamber pop","indie soul"] }
]

I will then make a "mapping" object so each child gets a parent genre assigned to them. I shall be doing this manually (if you have ideas on doing it automatically through code, that’d be great too, but not the core issue for the question)

genres = [
{
name: "Pop",
children: [{name:"Chamber Pop"},{name:"Indie Pop"}]
},
{
name: "R&B",
children: [{name:"Dutch R&B"}]
},
{
name: "Soul",
children: [{name:"Indie Soul"}]
}
]

I now want to run through all tracks in "songs" and populate the size in the respective children of genres. Ideal Output should be:

genres = [
{
name: "Pop",
children: [{name:"Chamber Pop", size:2},{name:"Indie Pop", size:3}]
},
{
name: "R&B",
children: [{name:"Dutch R&B", size:1}]
},
{
name: "Soul",
children: [{name:"Indie Soul", size:2}]
}
]

Any help on this would be appreciated. I’ll be using javascript for this, happy to use lodash/underscore as well if it’s more efficient.

I know how to loop through tracks, but once I have a particular child genre, I’m not able to efficiently map it to the genres variable

2

Answers


  1. Step 1: make a function to count the number of song on each track genre

    Step 2: add the result to each name in children

    const songs = [
      { 
        track_name: "name of track" , 
        track_genres: ["chamber pop","indie pop"] },
      { 
        track_name: "name of track 2" , 
        track_genres: ["dutch r&b","indie soul", "indie pop"] },
      { 
        track_name: "name of track 3" , 
        track_genres: ["indie pop","chamber pop","indie soul"] }
    ]
    const genres = [
      {
        name: "Pop",
        children: [{name:"Chamber Pop"},{name:"Indie Pop"}]
      },
      {
        name: "R&B",
        children: [{name:"Dutch R&B"}]
      },
      {
        name: "Soul",
        children: [{name:"Indie Soul"}]
      }
    ]
    function countSongs(genre){
      return songs.filter(s => s.track_genres.map(g => g.toLowerCase())
      .includes(genre.toLowerCase())).length
    }
    const genresResult = genres.map(g => {
      return {...g, children: g.children.map(c=>{
        return {...c, size: countSongs(c.name)}
      })}
    })
    console.log(genresResult)
    .as-console-wrapper {max-height:100% !important}
    Login or Signup to reply.
  2. You can use forEach() to iterate over the genres and each children array. Now you can find out how often the genre is used by filtering the songs array by genre. Note that you have mixed casing in the songs and genres array. I solved it by using toLowerCase(), but you may want to fix your data instead.

    const songs = [
      {
        track_name: "name of track",
        track_genres: ["chamber pop", "indie pop"],
      },
      {
        track_name: "name of track 2",
        track_genres: ["dutch r&b", "indie soul", "indie pop"],
      },
      {
        track_name: "name of track 3",
        track_genres: ["indie pop", "chamber pop", "indie soul"],
      },
    ];
    const genres = [
      {
        name: "Pop",
        children: [{ name: "Chamber Pop" }, { name: "Indie Pop" }],
      },
      {
        name: "R&B",
        children: [{ name: "Dutch R&B" }],
      },
      {
        name: "Soul",
        children: [{ name: "Indie Soul" }],
      },
    ];
    genres.forEach(({ children }) => {
      children.forEach((child) => {
        child.size = songs.filter((song) =>
          song.track_genres.includes(child.name.toLowerCase()),
        ).length;
      });
    });
    console.log(genres);

    Note that this solution mutates the genres array. If you want to keep the genres array as-is and generate a new array, you should use map() instead of forEach() and return the modified data.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search