phitsch
phitsch

Reputation: 855

Swift: Find value in array and return specific key

Im new to swift and would appreciate your help..

Problem:

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.

My example:

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

Answers (6)

Alexander
Alexander

Reputation: 63167

Using filter(_:)

let stringToSearch = "PC"
let pcHobbiests = persons.filter { $0.hobbies.contains(stringToSearch) }
let pcHobbiestNames = persons.map { $0.name }

Explaination

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

Luca Angeletti
Luca Angeletti

Reputation: 59496

Using reduce

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]
}

One liner (but don't do it at home!)

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

Duyen-Hoa
Duyen-Hoa

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

ellman121
ellman121

Reputation: 1835

Use Swift's for-in loop.

for pers in persons {
    if pers.hobbies.contains(StringToSearch) {
        nameOfPCGamer = pers.name
    }
}

Upvotes: 1

Jean-Baptiste Yun&#232;s
Jean-Baptiste Yun&#232;s

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

Code Different
Code Different

Reputation: 93151

Use flatMap:

let result = persons.flatMap {
    $0.hobbies.contains(StringToSearch) ? $0.name : nil
}

Upvotes: 4

Related Questions