-1

Using the example from here How to find the max value in a Swift object array?, how do you return the Usr element rather than the Int age value?

class Usr {
    var age: Int

    init(_ age: Int) {
        self.age = age
    }
}

let users = [Usr(1), Usr(8), Usr(5)]

let maxAge = users.map{$0.age}.max() //this returns 8 instead of the instance
Community
  • 1
  • 1
4thSpace
  • 43,672
  • 97
  • 296
  • 475
  • Use there Comparable protocol on user to make max work. Then you can use `users.max()` and it will return the user you want. – Fogmeister Dec 26 '16 at 23:34
  • 2
    The `max` function can also take a custom predicate to compare elements – did you see [this answer](http://stackoverflow.com/a/41217004/2976878) to the question you linked to? It'll return the `Usr` with the maximum age, or `nil` if the array is empty. – Hamish Dec 26 '16 at 23:45

2 Answers2

4

There are lots of great ways to do this in Swift. A quick and easy way is to use the reduce function:

let users = [Usr(1), Usr(8), Usr(5)]

let max: Usr = users.reduce(Usr(Int.min)) {
    ($0.age > $1.age) ? $0 : $1
}

print(max.age) // 8

You can also make your Usr conform to the Comparable protocol and use the max() function:

extension Usr: Comparable {}

func ==(lhs: Usr, rhs: Usr) -> Bool {
    return lhs.age < rhs.age
}

func <(lhs: Usr, rhs: Usr) -> Bool {
    return lhs.age < rhs.age
}

let maxUser = users.max()

Of course you can also use a more traditional loop as well:

var maxUser = users[0]
for user in users {
    if user.age > maxUser.age {
        maxUser = user
    }
}
nathangitter
  • 9,607
  • 3
  • 33
  • 42
4

There might be shorter options but this is one way:

let maxAgeUser = users.reduce(users.first, { $0!.age > $1.age ? $0 : $1 })
Keiwan
  • 8,031
  • 5
  • 36
  • 49
  • You can replace the whole `$0!.age > $1.age ? $0 : $1` with `max($0.age, $1.age)` to make it even shorter. So it would be `let maxAgeUser = users.reduce(users.first, { max($0.age, $1.age) })` – ngngngn Dec 31 '16 at 23:59