Home > Back-end >  Finding an Element within an Array efficiently [Swift]
Finding an Element within an Array efficiently [Swift]

Time:01-13

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
}

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

  •  Tags:  
  • Related