Compare commits

...

3 Commits

View File

@ -31,7 +31,11 @@ enum MusicGenre:
case Rock, Soul, Blues, Folk, Funk, Reggae, HipHop, NewWave, Electro, Metal case Rock, Soul, Blues, Folk, Funk, Reggae, HipHop, NewWave, Electro, Metal
// Define an Album with a union between a String and a MusicGenre // Define an Album with a union between a String and a MusicGenre
class Album(title: String, label: String, genre: String|MusicGenre) class Album(title: String, label: String, genre: String|MusicGenre) {
def getGenre(): String | MusicGenre = {
genre
}
}
class Streak(val s: String) { class Streak(val s: String) {
val streak: Option[Int] = { val streak: Option[Int] = {
@ -102,20 +106,33 @@ case class TopSongs(songs: List[Song] = List()) {
}) })
} }
// This function filter the songs by a specific music gender
def filterByGenre(genre: MusicGenre): List[Song] = {
songs.filter(song => song.album.exists(_.getGenre() == genre))
}
// This function counts the number of songs by each artist // This function counts the number of songs by each artist
// It uses flatMap to extract the artist names from the songs // It uses flatMap to extract the artist names from the songs
// Then it groups the songs by artist name and counts the occurrences // Then it groups the songs by artist name and counts the occurrences
// Finally, it returns a map with the artist names as keys and the counts as values // Finally, it returns a map with the artist names as keys and the counts as values
def countSongsByArtist(songs: List[Song]): Map[String, Int] = { def countSongsByArtist(): Map[String, Int] = {
songs.flatMap(_.singer.map(_.person.name)) songs.flatMap(_.singer.map(_.person.name))
.groupBy(identity) .groupBy(identity)
.view.mapValues(_.size) .view.mapValues(_.size)
.toMap .toMap
} }
// This function return the song spent the most weeks on the chart
// It uses reduce to find the song with the maximum streak value
def longestStreak(): Song = {
songs.reduce((s1, s2) => {
if (s1.rank._1.streak.getOrElse(0) > s2.rank._1.streak.getOrElse(0)) s1 else s2
})
}
// This function returns the top N songs by weeks on chart // This function returns the top N songs by weeks on chart
// It sorts the songs by the streak value in descending order and takes the top N songs // It sorts the songs by the streak value in descending order and takes the top N songs
def topNSongsByWeeks(songs: List[Song], n: Int): List[Song] = { def topNSongsByWeeks(n: Int): List[Song] = {
songs.sortBy(song => -song.rank._1.streak.getOrElse(0)).take(n) songs.sortBy(song => -song.rank._1.streak.getOrElse(0)).take(n)
} }
@ -156,19 +173,25 @@ case class TopSongs(songs: List[Song] = List()) {
// print the songs // print the songs
topSongs.printSongs() topSongs.printSongs()
println("----------"); println("----------")
// print the number of songs by artist // print the number of songs by artist
val songsByArtist = topSongs.countSongsByArtist(topSongs.songs) val songsByArtist = topSongs.countSongsByArtist()
println("Number of songs by artist:") println("Number of songs by artist:")
songsByArtist.foreach { songsByArtist.foreach {
case (artist, count) => println(s"$artist: $count") case (artist, count) => println(s"$artist: $count")
} }
println("----------"); println("----------")
// print the longest streak
val longestStreakSong = topSongs.longestStreak()
println(s"Longest streak: ${longestStreakSong.title} by ${longestStreakSong.singer.map(_.person.name).mkString(", ")} - ${longestStreakSong.rank._1.streak.getOrElse(0)} weeks")
println("----------")
// print the top N songs by weeks on chart // print the top N songs by weeks on chart
val topNSongs = topSongs.topNSongsByWeeks(topSongs.songs, 5) val topNSongs = topSongs.topNSongsByWeeks(5)
println("Top N songs by weeks on chart:") println("Top N songs by weeks on chart:")
topNSongs.foreach { song => topNSongs.foreach { song =>
println(s"${song.title} by ${song.singer.map(_.person.name).mkString(", ")} - ${song.rank._1.streak.getOrElse(0)} weeks") println(s"${song.title} by ${song.singer.map(_.person.name).mkString(", ")} - ${song.rank._1.streak.getOrElse(0)} weeks")