Reputation: 81
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
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
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
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