diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..b426168 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + + + { + "type": "node", + "request": "launch", + "name": "Launch Program", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/index.js" + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index e15a251..0000000 --- a/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# ๐Ÿš€ Lab: Native Array Methods pt.2 - - This lab is an opportunity to enhance your JavaScript skills through hands-on practice with array methods `forEach`, `map`, `find`, `some/every`, and `sort()`. - -## Getting Started - -### 1. ๐Ÿด Clone the Repository (from Github) -- On the GitHub page of this repository, click the green "Code" button. -- Copy the URL provided under "Clone with HTTPS". -- Open your terminal and execute: - ``` - git clone [paste the URL here] - ``` -- This command clones the repository to your local machine. - -### 1a. ๐Ÿด Clone the Repository (without Github) - -1. **Clone the Repository Directly:** - - Open your terminal on your local machine. - -2. **Clone Using Terminal:** - - Execute the following command to clone the repository (replace `[paste the URL here]` with the URL you provided): - ``` - git clone https://github.com/CastonPursuit/Lab-Native-Array-Methods-Pt2.git - ``` - - This command will clone the repository to your local machine. - - -### 2. ๐Ÿ” Explore the Problems -- In your terminal, navigate to the cloned repository's directory: - ``` - cd Lab-Native-Array-Methods-Pt2 - ``` -- Open the project in VS Code by typing: - ``` - code . - ``` -- You will find the `index.js` file containing 20 problems, each using a different array method. - -### 3. ๐Ÿ’ก Work on the Problems -- Each problem in `index.js` focuses on practicing a specific array method. -- Read the instructions for each problem and try to solve it. -- Use `console.log()` within your solutions to output results. - -### 4. ๐Ÿƒ Run Your Code -- Test your solutions by running: - ``` - node index.js - ``` -- This command executes your code in `index.js`, allowing you to see the output in the terminal. - -### 5. ๐Ÿงช Test Your Solutions -- To ensure your solutions are correct, use: - ``` - npm test - ``` -- This will run any predefined tests to validate your solutions. - -### 6. ๐Ÿ’พ Save Your Progress -- After solving each problem and verifying your solution, commit your progress: - ``` - git add . - git commit -m 'Completed problem # using Y method' - ``` -- Replace `#` with the problem number and `Y` with the array method used. - -### 7. ๐Ÿ”„ Repeat -- Continue working through each problem, running your code, testing, and committing your solutions. - -### 8. ๐Ÿš€ Next Steps -- After completing all the problems, you're ready for the next phase of your learning journey. -- In the upcoming lesson, you'll learn how to push your solutions back to GitHub, sharing your progress and receiving feedback. - -### 9. ๐Ÿ†˜ Need Help? -- If you find yourself stuck on a problem, don't hesitate to review the [MDN Web Docs on Array methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array). -- Collaboration is key to learning. Feel free to discuss approaches with your peers or reach out to a coach for guidance. - diff --git a/data/songs.js b/data/songs.js index 6fd56d6..0ad05d8 100644 --- a/data/songs.js +++ b/data/songs.js @@ -137,7 +137,7 @@ const songs = [ album: "Seasonal Sounds", artist: "Melody Green", runtimeInSeconds: 152, - } + }, ]; module.exports = songs; diff --git a/index.js b/index.js index 2bb3c16..1ec1175 100644 --- a/index.js +++ b/index.js @@ -3,6 +3,7 @@ Native Array Methods pt.2 continues with the same dataset: songs. All required f */ +const { ECDH } = require("crypto"); const exampleSongData = require("./data/songs"); // Do not change the line above. @@ -13,7 +14,9 @@ const exampleSongData = require("./data/songs"); * @param {Object[]} songs - An array of songs. * @returns {string[]} Sorted song titles. */ -function getSortedTitles(songs) {} +function getSortedTitles(songs) { + return songs.map(x => x.title).sort(); +} // #2 /** @@ -22,7 +25,10 @@ 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.map(song => song.album === albumName ? song.title : null).filter(Boolean) +} + // #3 /** @@ -30,7 +36,18 @@ function getSongsFromAlbum(songs, albumName) {} * @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) { + return songs.reduce((runtimeObject, song) => { + if(song.runtimeInSeconds < 180) { + runtimeObject.shortSongs++ + }else if(song.runtimeInSeconds >= 180 && song.runtimeInSeconds <= 300) { + runtimeObject.mediumSongs++ + }else if(song.runtimeInSeconds > 300) { + runtimeObject.longSongs++ + } + return runtimeObject + }, {shortSongs: 0, mediumSongs: 0, longSongs: 0}) +} // #4 /** @@ -38,7 +55,21 @@ 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) { + let albums = songs.map(song => song.album) + let mostSongsValue = 0 + let album; + albums.reduce((albumsObject, currAlbum) => { + albumsObject[currAlbum] = (albumsObject[currAlbum] || 0) + 1 + if(albumsObject[currAlbum] > mostSongsValue) { + mostSongsValue = albumsObject[currAlbum] + album = currAlbum + } + return albumsObject + },{}) + return album +} + // #5 /** @@ -47,7 +78,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.find(song => song.album === albumName) +} // #6 /** @@ -56,7 +89,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 +99,10 @@ 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) { + songs.forEach(song => song["durationInMinutes"] = song.runtimeInSeconds / 60) + return songs +} // #8 /** @@ -72,7 +110,16 @@ 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) { + let albumArray = songs.map(song => song.album).sort((a, b) => { + if(a > b) { + return -1 + }else { + return 1 + } + }); + return albumArray.filter((album, index) => albumArray.indexOf(album) === index) +} // #9 /** @@ -81,7 +128,10 @@ 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.filter(song => song.title.includes(word)).map(song => song.title); +} + // #10 /** @@ -90,21 +140,64 @@ 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.reduce((total, song) => { + if(song.artist == artistName){ + total += song.runtimeInSeconds + } + return total + },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 artist = songs.map(song => song.artist) + return artist.reduce((artistObject, currArtist) => { + artistObject[currArtist] = (artistObject[currArtist] || 0) + 1 + if(artistObject[currArtist] > 1) { + console.log(currArtist) + } + return artistObject + },{}) + // let obj = {} + // for(let i = 0; i < songs.length; i++) { + // if(obj.hasOwnProperty(songs[i].artist)){ + // continue; + // } + // obj[songs[i].artist] = 0 + // } + // for(let j = 0; j < artist.length; j++) { + // for(let key in obj) { + // if(artist[j] === key){ + // obj[key]++ + // } + // } + // } + // for(let key in obj) { + // if(obj[key] > 1 ) { + // console.log(key) + // } + // } +} // Problem #12 /** * Logs the longest song title. * @param {Object[]} songs - An array of songs. */ -function printLongestSongTitle(songs) {} +function printLongestSongTitle(songs) { + let longestSong = songs.reduce((longest, song) => { + if(longest.length < song.title.length) { + longest = song.title + } + return longest + },"") + console.log(longestSong) +} // Problem #13 /** @@ -112,7 +205,11 @@ 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((a, b) => { + return a.artist.localeCompare(b.artist) || a.title.localeCompare(b.title); + }) +} // Problem #14 /** @@ -120,7 +217,12 @@ 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) { + return songs.reduce((obj, song) => { + obj[song.album] = (obj[song.album] || 0) + song.runtimeInSeconds + return obj; + },{}) +} // Problem #15 /** @@ -129,7 +231,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) || null; +} // Problem #16 /** @@ -137,7 +241,16 @@ 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) { + // * MY CODE + return songs.reduce((object, song) => { + let arr = [] + arr.push(song.title) + object[song.artist] = (object[song.artist] || []).concat(arr) + return object + },{}) +} // Problem #17 /** @@ -145,21 +258,84 @@ 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) {} +// object[song.album] = (object[song.album] || r) += song.runtimeInSeconds && object[song.album].songCount++ + +function findAlbumWithLongestAverageRuntime(songs) { + let longestAvg = 0 + let albumName = "" + songs.reduce((object, song) => { + if(!object[song.album]){ + object[song.album] = { + runtimes: song.runtimeInSeconds, + songCount: 1 + } + }else { + object[song.album].runtimes += song.runtimeInSeconds + object[song.album].songCount++ + } + let average = object[song.album].runtimes / object[song.album].songCount + if(average > longestAvg) { + longestAvg = average + albumName = song.album + } + return object + },{}) + return albumName; +} // Problem #18 /** * Logs song titles sorted by their runtime. * @param {Object[]} songs - An array of songs. */ -function printSongsSortedByRuntime(songs) {} +function printSongsSortedByRuntime(songs) { + songs.sort((a, b) => a.runtimeInSeconds - b.runtimeInSeconds) + .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) { + // * CLASSCODE + // let albumSummaries = {}; + // songs.forEach(song => { + // if(!albumSummaries[song.album]){ + // albumSummaries[song.album] = { + // albumName: song.album, + // songCount: 1, + // totalRuntime: song.runtimeInSeconds + // } + // }else { + // albumSummaries[song.album].songCount++; + // albumSummaries[song.album].totalRuntime += song.runtimeInSeconds; + // } + // }) + // for(const summary in albumSummaries) { + // console.log(`${albumSummaries[summary].albumName}: ${albumSummaries[summary].songCount} songs, Total Runtime: ${albumSummaries[summary].totalRuntime} seconds`) + // // To account for the s in a plural value ^ ${albumSummaries[summary].songCount > 1 ? "s" : ""} + // } + + // * MYCODE + let object = songs.reduce((obj, song) => { + if(!obj[song.album]) { + obj[song.album] = { + albumName : song.album, + songCount : 1, + totalRuntime : song.runtimeInSeconds + } + }else { + obj[song.album].songCount++ + obj[song.album].totalRuntime += song.runtimeInSeconds + } + return obj + },{}) + for(const album in object){ + console.log(`${object[album].albumName}: ${object[album].songCount} songs, Total Runtime: ${object[album].totalRuntime} seconds`) + } +} // Problem #20 /** @@ -167,8 +343,40 @@ 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) { + let artists = songs.map(song => song.artist) + // let artistWithSongsObject = {}; + let artistWithMost; + let highestValue = 0 + artists.reduce((artistObject, currArtist) => { + artistObject[currArtist] = (artistObject[currArtist] || 0) + 1 + if(highestValue < artistObject[currArtist]) { + highestValue = artistObject[currArtist] + artistWithMost = currArtist + } + return artistObject + },{}) + return artistWithMost + // for(const artist of artists) { + // let totalSongs = 0 + // for(const song of songs) { + // if(artist === song.artist) { + // totalSongs++ + // } + // } + // if(artistWithSongsObject.hasOwnProperty(artist)){ + // continue; + // } + // artistWithSongsObject[artist] = totalSongs + // } + // for(const key in artistWithSongsObject){ + // if(artistWithSongsObject[key] > highestValue){ + // artistWithMost = key + // highestValue = artistWithSongsObject[key] + // } + // } + // return artistWithMost +} module.exports = { getSortedTitles, diff --git a/practiceLane.js b/practiceLane.js new file mode 100644 index 0000000..653ce2b --- /dev/null +++ b/practiceLane.js @@ -0,0 +1,28 @@ +const exampleSongData = require("./data/songs"); + +function findAlbumWithLongestAverageRuntime(songs) { + let longest = 0 + let albumName = "" + let mappedObject = songs.reduce((object, song) => { + if(!object[song.album]){ + object[song.album] = { + runtimes: song.runtimeInSeconds, + songCount: 1 + } + }else { + object[song.album].runtimes += song.runtimeInSeconds + object[song.album].songCount++ + } + return object + },{}) + for(const album in mappedObject) { + let average = mappedObject[album].runtimes / mappedObject[album].songCount + if(average > longest) { + longest = average + albumName = album + } + } + return albumName +} + + console.log(findAlbumWithLongestAverageRuntime(exampleSongData)) \ No newline at end of file