-2

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?

nix.codes
  • 388
  • 2
  • 20
  • use default property ```team.roster.first{where: .....``` – Raja Kishan Jan 13 '22 at 04:49
  • [https://developer.apple.com/documentation/swift/array/1848165-first](https://developer.apple.com/documentation/swift/array/1848165-first) – Ricky Mo Jan 13 '22 at 05:12
  • If the entries are sorted by their id then you can do a binary search. Or you can maintain an index. Otherwise you'll always have to traverse the array to find a matching entry. Using `first(where:)` does not make it more efficient. – Martin R Jan 13 '22 at 05:42
  • To clarify, by "maintain an index", Martin is talking about building a dictionary that maps IDs to players. You pay some up-front cost, but subsequent repeated look-ups become faster. – Alexander Jan 13 '22 at 06:24

3 Answers3

0

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")
0

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

https://www.geeksforgeeks.org/binary-search/

Ruben Mim
  • 136
  • 1
  • 6
-1
let name = team.roster.first(where: { $0["player_id"] == id}).map{ $0["player_name"] }
Shabnam Siddiqui
  • 579
  • 4
  • 13