Reputation: 855
Im new to swift and would appreciate your help..
In my future project I would love to look for a specific String in an Array and get only the names back who have this value in their hobbies Array.
struct Person {
var name: String
var hobbies:Set <String>
}
var persons: [Person]
persons = [
Person(name: "Steve", hobbies: ["PC", "PS4", "Gaming", "Basketball"]),
Person(name: "Max", hobbies: ["Gaming", "Xbox", "cooking", "PC"]),
Person(name: "Julia", hobbies: ["Soccer", "Tennis", "cooking", "Painting"])
]
var StringToSearch = "PC"
I would love to get only the names back who hobbies "PC" is. How can I iterate through my collection and get only the keys instead of the values back like in a dictionary? Thank you!
Upvotes: 4
Views: 4204
Reputation: 63167
filter(_:)
let stringToSearch = "PC"
let pcHobbiests = persons.filter { $0.hobbies.contains(stringToSearch) }
let pcHobbiestNames = persons.map { $0.name }
filter(_:)
will iterate over elements of a Sequence
, building up a new Array containing only those elements for which closure evaluates to true. In this instance, the closure checks if the hobbies
Array
of the currently iteration's Person
contains stringToSearch
.
You can then iterate over your pcHobbiests Array or use them as you please:
for pcHobbiest in pcHobbiests {
print(pcHobbiest)
}
Upvotes: 3
Reputation: 59496
After map
, filter
and flatMap
here's my solution with reduce
:)
let names = persons.reduce([String]()) { (names, person) -> [String] in
guard person.hobbies.contains(keyword) else { return names }
return names + [person.name]
}
And if your really want to write everything on 1 line...
let names = persons.reduce([String]()) { $0.0 + ($0.1.hobbies.contains(keyword) ? [$0.1.name] : []) }
Upvotes: 2
Reputation: 15784
you can use filter + map to return name array of all people who have "PC" hobbies:
let nameArray = persons.filter{$0.hobbies.contains("PC")}.map{$0.name}
//return ["Steve", "Max"]
Upvotes: 3
Reputation: 1835
Use Swift's for-in loop.
for pers in persons {
if pers.hobbies.contains(StringToSearch) {
nameOfPCGamer = pers.name
}
}
Upvotes: 1
Reputation: 36391
You may use a loop, collect:
for p in persons {
if p.hobbies.contains("PC") {
// then you've got one!
}
}
or you can use a more generic programming by filtering the array, thus obtaining an array of filtered content and iterating on it:
for p in persons.filter({$0.hoobies.contains("PC")}) {
// got one...
}
Upvotes: -2
Reputation: 93151
Use flatMap
:
let result = persons.flatMap {
$0.hobbies.contains(StringToSearch) ? $0.name : nil
}
Upvotes: 4