Why does it return to the console like this?

Could someone explain why the code below:


let artists = ["Brenda and the Del-chords", "Brenda and the Del-chords", "Fizz", "Boom!"]

let durations = [90, 200, 150, 440]



func songInformation(title: String, artist: String, duration: Int) -> String {

    return "The song is called \(songTitles) by \(artists) and is \(durations) seconds long"

}



for i in 0 ... songTitles.count - 1 {

    print(songInformation(title: songTitles[i], artist: artists[i], duration: durations[i]))

}

returns the following to the console:

The song is called ["Ooh yeah", "Maybe", "No, no, no", "Makin\' up your mind"] by ["Brenda and the Del-chords", "Brenda and the Del-chords", "Fizz", "Boom!"] and is [90, 200, 150, 440] seconds long 

The song is called ["Ooh yeah", "Maybe", "No, no, no", "Makin\' up your mind"] by ["Brenda and the Del-chords", "Brenda and the Del-chords", "Fizz", "Boom!"] and is [90, 200, 150, 440] seconds long

The song is called ["Ooh yeah", "Maybe", "No, no, no", "Makin\' up your mind"] by ["Brenda and the Del-chords", "Brenda and the Del-chords", "Fizz", "Boom!"] and is [90, 200, 150, 440] seconds long

The song is called ["Ooh yeah", "Maybe", "No, no, no", "Makin\' up your mind"] by ["Brenda and the Del-chords", "Brenda and the Del-chords", "Fizz", "Boom!"] and is [90, 200, 150, 440] seconds long

I was expecting it to return something more like:

The song is called Ooh yeah by Brenda and the Del-Chords and is 90 seconds long.

It does what you ask !

func songInformation(title: String, artist: String, duration: Int) -> String {
    return "The song is called \(songTitles) by \(artists) and is \(durations) seconds long"
}

you use songTitles, artists and durations, so it prints the arrays.

Just change for:

func songInformation(title: String, artist: String, duration: Int) -> String {
    return "The song is called \(title) by \(artist) and is \(duration) seconds long"
}

However, it is a bit risky to have several arrays which need to be synchronised. If you add a song in one and forget to add in others or do not insert at the same position, that will not work.

A good practice in Swift is to create a struct:

struct Song {
  var title   : String // Could be let as well as you don't need to change later)
  var artist  : String
  var duration: Int
}

You declare each song with all its information in one instance:

let songs = [
    Song(title: "Ooh yeah", artist: "Brenda and the Del-chords", duration: 90),
		Song(title: "Maybe", artist: "Brenda and the Del-chords", duration: 200),
		Song(title: "No, no, no", artist: "Fizz", duration: 150),
		Song(title: "Makin\' up your mind", artist: "Boom!", duration: 440)
     ]

Much less error prone.

The func becomes:

func songInformation(song: Song) -> String {
    return "The song is called \(song.title) by \(song.artist) and is \(song.duration) seconds long"
}

And the loop:

for song in songs {
    print(songInformation(song: song))
}

For better readability, you can also eliminate the label in the func call:

func songInformation(_ song: Song) -> String {
    return "The song is called \(song.title) by \(song.artist) and is \(song.duration) seconds long"
}

for song in songs {
    print(songInformation(song))
}
Why does it return to the console like this?
 
 
Q