diff --git a/index.js b/index.js index 2bb3c16..504c8e7 100644 --- a/index.js +++ b/index.js @@ -1,19 +1,22 @@ -/* -Native Array Methods pt.2 continues with the same dataset: songs. All required functions and array methods (forEach, map, find, some/every, sort) are combined into a single file, each addressing a distinct problem. -*/ - +/**********************************************************************************/ +/* Native Array Methods pt.2 continues with the same dataset: songs. */ +/* All required functions and array methods (forEach, map, find, some/every, sort) */ +/* are combined into a single file, each addressing a distinct problem. */ +/**********************************************************************************/ +const songs = require("./data/songs"); const exampleSongData = require("./data/songs"); // Do not change the line above. - // #1 /** * Returns the titles of songs sorted alphabetically. * @param {Object[]} songs - An array of songs. * @returns {string[]} Sorted song titles. */ -function getSortedTitles(songs) {} +function getSortedTitles(songs) { + return songs.map((song) => song.title).sort(); +} // #2 /** @@ -22,15 +25,30 @@ function getSortedTitles(songs) {} * @param {string} albumName - Name of the album. * @returns {string[]} An array of song titles. */ -function getSongsFromAlbum(songs, albumName) {} +function getSongsFromAlbum(songs, albumName) { + return songs + .filter((song) => song.album == albumName) + .map((song) => song.title); +} -// #3 +// #3 /** * Categorizes and counts songs based on their runtime. * @param {Object[]} songs - An array of songs. * @returns {Object} An object with counts of short, medium, and long songs. */ -function categorizeSongsByRuntime(songs) {} +function categorizeSongsByRuntime(songs) { + const short = songs.filter((song) => song.runtimeInSeconds < 180); + const medium = songs.filter( + (song) => song.runtimeInSeconds >= 180 && song.runtimeInSeconds < 300 + ); + const long = songs.filter((song) => song.runtimeInSeconds >= 300); + return { + shortSongs: short.length, + mediumSongs: medium.length, + longSongs: long.length, + }; +} // #4 /** @@ -38,7 +56,23 @@ function categorizeSongsByRuntime(songs) {} * @param {Object[]} songs - An array of songs. * @returns {string} The name of the album with the most songs. */ -function findAlbumWithMostSongs(songs) {} +function findAlbumWithMostSongs(songs) { + const outputAlbum = { + name: "", + numSongs: 0, + }; + let albuns = songs.map((song) => song.album); + albuns + .filter((album, idx) => albuns.indexOf(album) === idx) + .forEach((album) => { + const numSongs = songs.filter((song) => song.album == album).length; + if (outputAlbum.numSongs <= numSongs) { + outputAlbum.name = album; + outputAlbum.numSongs = numSongs; + } + }); + return outputAlbum.name; +} // #5 /** @@ -47,7 +81,9 @@ function findAlbumWithMostSongs(songs) {} * @param {string} albumName - Name of the album. * @returns {Object|null} First song object in the album or null. */ -function getFirstSongInAlbum(songs, albumName) {} +function getFirstSongInAlbum(songs, albumName) { + return songs.filter((song) => song.album == albumName)[0]; +} // #6 /** @@ -56,7 +92,9 @@ function getFirstSongInAlbum(songs, albumName) {} * @param {number} runtime - The runtime to check against in seconds. * @returns {boolean} True if there is at least one song longer than the runtime. */ -function isThereLongSong(songs, runtime) {} +function isThereLongSong(songs, runtime) { + return songs.some((song) => song.runtimeInSeconds > runtime); +} // #7 /** @@ -64,7 +102,12 @@ function isThereLongSong(songs, runtime) {} * @param {Object[]} songs - An array of songs. * @returns {Object[]} Array of song objects with runtime in minutes. */ -function getSongsWithDurationInMinutes(songs) {} +function getSongsWithDurationInMinutes(songs) { + return songs.map((song) => { + song.durationInMinutes = song.runtimeInSeconds / 60; + return song; + }); +} // #8 /** @@ -72,7 +115,21 @@ function getSongsWithDurationInMinutes(songs) {} * @param {Object[]} songs - An array of songs. * @returns {string[]} Array of album names in reverse alphabetical order. */ -function getAlbumsInReverseOrder(songs) {} +function getAlbumsInReverseOrder(songs) { + const albuns = []; + songs.forEach((song) => { + if (!albuns.includes(song.album)) { + albuns.push(song.album); + } + }); + return albuns.sort((a, b) => { + if (a < b) { + return 1; + } else { + return -1; + } + }); +} // #9 /** @@ -81,7 +138,15 @@ function getAlbumsInReverseOrder(songs) {} * @param {string} word - The word to search for in song titles. * @returns {string[]} An array of song titles containing the word. */ -function songsWithWord(songs, word) {} +function songsWithWord(songs, word) { + return songs + .map((song) => song.title) + .filter((song) => { + if (song.includes(word)) { + return song; + } + }); +} // #10 /** @@ -90,21 +155,43 @@ function songsWithWord(songs, word) {} * @param {string} artistName - Name of the artist. * @returns {number} Total runtime in seconds. */ -function getTotalRuntimeOfArtist(songs, artistName) {} +function getTotalRuntimeOfArtist(songs, artistName) { + return songs + .filter((song) => song.artist == artistName) + .reduce((totalRuntime, song) => (totalRuntime += song.runtimeInSeconds), 0); +} // Problem #11 /** * Prints artists who have more than one song in the list. * @param {Object[]} songs - An array of songs. */ -function printArtistsWithMultipleSongs(songs) {} +function printArtistsWithMultipleSongs(songs) { + let artists = songs.map((song) => song.artist); + artists + .filter((artist, idx) => artists.indexOf(artist) === idx) + .forEach((artist) => { + const artistSongs = songs.filter((song) => song.artist == artist); + if (artistSongs.length > 1) { + console.log(artist); + } + }); +} // Problem #12 /** * Logs the longest song title. * @param {Object[]} songs - An array of songs. */ -function printLongestSongTitle(songs) {} +function printLongestSongTitle(songs) { + let longestSongTitle = ""; + songs.forEach((song) => { + if (song.title.length > longestSongTitle.length) { + longestSongTitle = song.title; + } + }); + console.log(longestSongTitle); +} // Problem #13 /** @@ -112,7 +199,13 @@ function printLongestSongTitle(songs) {} * @param {Object[]} songs - An array of songs. * @returns {Object[]} Sorted array of songs. */ -function sortSongsByArtistAndTitle(songs) {} +function sortSongsByArtistAndTitle(songs) { + return songs.sort((songA, songB) => { + const artistCompare = songA.artist.localeCompare(songB.artist); + const titleCompare = songA.title.localeCompare(songB.title); + return artistCompare || titleCompare; + }); +} // Problem #14 /** @@ -120,7 +213,17 @@ function sortSongsByArtistAndTitle(songs) {} * @param {Object[]} songs - An array of songs. * @returns {Object} An object mapping each album to its total runtime. */ -function listAlbumTotalRuntimes(songs) {} +function listAlbumTotalRuntimes(songs) { + const albumTotalRuntimes = {}; + songs.forEach((song) => { + if (albumTotalRuntimes.hasOwnProperty(song.album)) { + albumTotalRuntimes[song.album] += song.runtimeInSeconds; + } else { + albumTotalRuntimes[song.album] = song.runtimeInSeconds; + } + }); + return albumTotalRuntimes; +} // Problem #15 /** @@ -129,7 +232,9 @@ function listAlbumTotalRuntimes(songs) {} * @param {string} letter - The letter to search for. * @returns {Object|null} The first song object that matches the criterion or null. */ -function findFirstSongStartingWith(songs, letter) {} +function findFirstSongStartingWith(songs, letter) { + return songs.find((song) => song.title[0] == letter.toUpperCase()); +} // Problem #16 /** @@ -137,7 +242,17 @@ function findFirstSongStartingWith(songs, letter) {} * @param {Object[]} songs - An array of songs. * @returns {Object} An object mapping each artist to an array of their song titles. */ -function mapArtistsToSongs(songs) {} +function mapArtistsToSongs(songs) { + const artistSongs = {}; + songs.forEach((song) => { + if (artistSongs.hasOwnProperty(song.artist)) { + artistSongs[song.artist].push(song.title); + } else { + artistSongs[song.artist] = [song.title]; + } + }); + return artistSongs; +} // Problem #17 /** @@ -145,21 +260,67 @@ function mapArtistsToSongs(songs) {} * @param {Object[]} songs - An array of songs. * @returns {string} The name of the album with the longest average song runtime. */ -function findAlbumWithLongestAverageRuntime(songs) {} +function findAlbumWithLongestAverageRuntime(songs) { + const outputAlbum = { + name: "", + avgRuntime: 0, + }; + let albuns = songs.map((song) => song.album); + albuns + .filter((album, idx) => albuns.indexOf(album) === idx) + .forEach((albun) => { + const albumSongs = songs.filter((song) => song.album == albun); + const totalRuntime = albumSongs.reduce( + (acc, song) => acc + song.runtimeInSeconds, + 0 + ); + const avgRuntime = totalRuntime / albumSongs.length; + if (outputAlbum.avgRuntime <= avgRuntime) { + outputAlbum.name = albun; + outputAlbum.avgRuntime = avgRuntime; + } + }); + return outputAlbum.name; +} // Problem #18 /** * Logs song titles sorted by their runtime. * @param {Object[]} songs - An array of songs. */ -function printSongsSortedByRuntime(songs) {} +function printSongsSortedByRuntime(songs) { + return songs + .sort((songA, songB) => { + if (songA.runtimeInSeconds <= songB.runtimeInSeconds) { + return -1; + } else { + return 1; + } + }) + .forEach((song) => console.log(song.title)); +} // Problem #19 /** * Prints a summary of each album, including its name, total runtime, and number of songs. * @param {Object[]} songs - An array of songs. */ -function printAlbumSummaries(songs) {} +function printAlbumSummaries(songs) { + let albuns = songs.map((song) => song.album); + albuns = albuns + .filter((album, idx) => albuns.indexOf(album) === idx) + .forEach((album) => { + const albumSongs = songs.filter((song) => song.album == album); + const numSongs = albumSongs.length; + const totalRuntime = albumSongs.reduce( + (acc, song) => acc + song.runtimeInSeconds, + 0 + ); + console.log( + `${album}: ${numSongs} songs, Total Runtime: ${totalRuntime} seconds` + ); + }); +} // Problem #20 /** @@ -167,13 +328,30 @@ function printAlbumSummaries(songs) {} * @param {Object[]} songs - An array of songs. * @returns {string} The name of the artist with the most songs. */ -function findArtistWithMostSongs(songs) {} +function findArtistWithMostSongs(songs) { + const outputArtist = { + name: "", + numSongs: "", + }; + const artists = songs.map((song) => song.artist); + artists + .filter((artist, idx) => artists.indexOf(artist) === idx) + .forEach((artist) => { + const numSongs = songs.filter((song) => song.artist == artist).length; + + if (outputArtist.numSongs < numSongs) { + outputArtist.name = artist; + outputArtist.numSongs = numSongs; + } + }); + return outputArtist.name; +} module.exports = { getSortedTitles, getSongsFromAlbum, - categorizeSongsByRuntime, + categorizeSongsByRuntime, findAlbumWithMostSongs, getFirstSongInAlbum, isThereLongSong, @@ -190,5 +368,5 @@ module.exports = { findAlbumWithLongestAverageRuntime, printSongsSortedByRuntime, printAlbumSummaries, - findArtistWithMostSongs -};; + findArtistWithMostSongs, +};