Tom
Tom

Reputation: 81

Take keys from Dictionary and map them to an array

I'm trying to build a closure that does what my title says. My code runs but it does not print what I expected.

var names: [String] = []
var namesAndAges = ["Tom": 25, "Michael": 35, "Harry": 28, "Fabien": 16]

var ofAge = namesAndAges.filter { namesAndAges in namesAndAges.value > 18 }

var addNames = ofAge.map { ofAge in names.append(ofAge.key) }

print(addNames) //this prints [(), (), ()]

Upvotes: 0

Views: 47

Answers (3)

GetSwifty
GetSwifty

Reputation: 7756

To avoid looping more than once, this is how I do it:

var namesAndAges = ["Tom": 25, "Michael": 35, "Harry": 28, "Fabien": 16]
let addNames: [String] = namesAndAges.flatMap { $0.value > 18 ? $0.key : nil }
print(addNames) // prints ["Michael", "Harry", "Tom"]

(oh and it's shorter 🙃)

Upvotes: 0

Alexander
Alexander

Reputation: 63399

The issue you're experience is because names.append(ofAge.key) returns Void (a.k.a. the empty tuple, ()). map produces a new Array containing the return values of the given closure after it's been applied to every element of the source array (ofAge, in your example).

The names array will actually contain the data you want, but this isn't how map is meant to be used (you're essentially using it in place of forEach).

Try this instead:

var namesAndAges = ["Tom": 25, "Michael": 35, "Harry": 28, "Fabien": 16]
var namesOfAge = namesAndAges.filter { $0.value > 18 }.map{ $0.key }

print(namesOfAge)

Upvotes: 0

ninjaproger
ninjaproger

Reputation: 2044

Basically you are misusing filter and map methods. Try this:

var names: [String] = []
var namesAndAges = ["Tom": 25, "Michael": 35, "Harry": 28, "Fabien": 16]

var ofAge = namesAndAges.filter { $0.value > 18 }

var addNames = ofAge.map { $0.key }

print(addNames) //this prints ["Michael", "Harry", "Tom"]

Upvotes: 1

Related Questions