Keith Grimes
Keith Grimes

Reputation: 41

Trouble accessing items in an array of arrays in Swift

let arrayOfDwarfArrays = [["Sleepy", "Grumpy", "Doc"], ["Thorin", "Nori"]]

var dwarfArray: [String] = []
for dwarfName in arrayOfDwarfArrays {
    dwarfArray.append(dwarfName)
}

All I'm trying to do is access the values of the original array of arrays and append them to a new, single array. But I keep getting this error:

Cannot convert value of type '[String]' to expected argument type 'String'

In the simplest of terms, what am I doing wrong?

Upvotes: 2

Views: 204

Answers (3)

Leo Dabus
Leo Dabus

Reputation: 236568

No need to reinvent the wheel. You can use a Sequence instance method called joined(). It will return a FlattenCollection<[[String]]> which you can use to initialise a new array if needed:

let dwarfCollections = [["Sleepy", "Grumpy", "Doc"], ["Thorin", "Nori"]]

// Use 'joined()' to access each element of each collection:
for dwarf in dwarfCollections.joined() {
    print(dwarf)
}

If you need to create a new array just initialize it with the elements of the flatten collection:

let dwarfs = Array(dwarfCollections.joined())  // ["Sleepy", "Grumpy", "Doc", "Thorin", "Nori"]
print(dwarfs)

This will print

Sleepy

Grumpy

Doc

Thorin

Nori

["Sleepy", "Grumpy", "Doc", "Thorin", "Nori"]

Upvotes: 1

Anik Islam Abhi
Anik Islam Abhi

Reputation: 25352

That's happened because dwarfArray is an array of string and expecting a string to be appended. However, it's getting an array of string instead of just string.

Try like this

let arrayOfDwarfArrays = [["Sleepy", "Grumpy", "Doc"], ["Thorin", "Nori"]]

var dwarfArray: [String] = []
for dwarfName in arrayOfDwarfArrays {
    dwarfArray.append(contentsOf: dwarfName)
}

Upvotes: 1

Alexander
Alexander

Reputation: 63399

Array.append(_:) expects an argument of type Element, which is only a single element. Obviously, providing a [String] as an argument to this parameter would only work if Element is [String], i.e. if the array had type [[String]]. Since this isn't the case, Array.append(_:) is not the right choice.

Instead, you should use Array.append(contentsOf:), which expects an argument of type S, where S is any Sequence conforming type whose Element is the same as the Array's element. This is suitable for when you want to append all of the elements of a subarray (dwarfName).

let arrayOfDwarfArrays = [["Sleepy", "Grumpy", "Doc"], ["Thorin", "Nori"]]

var dwarfArray: [String] = []
for dwarfName in arrayOfDwarfArrays {
    dwarfArray.append(contentsOf: dwarfName)
}

In this particular case though, this code is even better expressed using a simple Array.flatMap(_:) operation:

let arrayOfDwarfArrays = [["Sleepy", "Grumpy", "Doc"], ["Thorin", "Nori"]]
let dwarfArray = arrayOfDwarfArrays.flatMap { $0 }

Upvotes: 1

Related Questions