Currently using the following to find a match within an array, but I want to know if there is a more efficient way of doing such a check.
for player in team.roster {
if id == player.id {
return player.name
}
}
Basically taking a variable that is given, a player id, and looping through a team roster to find a matching id, which given the size of the team is okay, but in the event a similar check is done on a larger data set what would be a better way to handle this?
CodePudding user response:
let name = team.roster.first(where: { $0["player_id"] == id}).map{ $0["player_name"] }
CodePudding user response:
You can user Filter if there is chance of more than one element to satisfy the condition.
struct Roster {
let name: String
let id: Int
init(name: String, id: Int) {
self.name = name
self.id = id
}
}
let roster = [Roster(name: "James", id: 25546),
Roster(name: "Jones", id: 5484),
Roster(name: "Bethany", id: 659),
Roster(name: "Mark", id: 45425546)]
To filter it use this, which will return an Array of one item.
let filtered = roster.filter { person in return person.id == 25546 }
Alternatively if you know that there is only a single element use first as Shabnam is suggesting.
CodePudding user response:
Use the default property first{ condition }
let id = 4
let roster: [TeamMember] = [.init(id: 1, name: "Abishek", age: 19),
.init(id: 2, name: "Dinesh", age: 22),
.init(id: 3, name: "Praveen", age: 24),
.init(id: 4, name: "Sam", age: 25),
.init(id: 5, name: "David", age: 21)]
let firstMember = roster.first{$0.id == id}
print(firstMember)
print(firstMember?.name)
Output
Optional(TeamMember(id: 4, name: "Sam", age: 25.0))
Optional("Sam")
CodePudding user response:
@Shabnam Siddiqui answer is Swifty and I would use it most of the time, but the binary search is worth to know as well.
The Swift method first(where:) in O(n)complexity https://developer.apple.com/documentation/swift/array/1848165-first, whereas a binary search has a worst-case performance of O(log n) and a best-case performance of O(1).
So assuming :
struct Player {
var id : Int
var name : String
}
for :
var players : [Player] = [
Player(id: 0, name: "Bob"),
Player(id: 1, name: "Edd"),
Player(id: 2, name: "Jo"),
Player(id: 3, name: "John")
]
Solution recursive :
func getPlayername(_ id : Int, _ players : [Player]) -> String?{
guard players.count > 0 else {
print("No players found with id \(id)")
return nil
}
if players.first!.id == id {
return players.first?.name
}else{
return getPlayername(id, Array(players.dropFirst()))
}
}
print(getPlayername(3, players))
Solution binary :
func getPlayerBinary(_ id : Int, _ players : [Player]) -> String?{
var startIndex = 0
var max = players.count
while startIndex < max {
let midIndex = startIndex (max - startIndex) / 2
if players[midIndex].id == id {
return players[midIndex].name
} else if players[midIndex].id < id {
lowerBound = midIndex 1
} else {
max = midIndex
}
}
print("No players found with id \(id)")
return nil
}
