Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

swift - sort an array of objects by their optional boolean property without force unwrapping

Tags:

ios

swift

I can sort this array of store objects by their 'flagship' boolean property, but how can I safely unwrap the 'flagship' property first?

let flagshipStores = self.stores.sort {
    $0.flagship! && !$1.flagship!
}
like image 235
Christian Tuskes Avatar asked Aug 20 '16 22:08

Christian Tuskes


4 Answers

let flagshipStores = self.stores.sort {
    guard let flagship0 = $0.flagship, let flagship1 = $1.flagship else { return false }
    return flagship0 && !flagship1
}
like image 130
mtaweel Avatar answered Nov 11 '22 22:11

mtaweel


One more approach: turn the Bool? into an Int, then compare the Ints. You get to specify how a nil value compares to non-nil values.

For instance, this sorts nil values before both false and true:

stores.sort { Int($0.flagship ?? -1) < Int($1.flagship ?? -1) }

This sorts nil values after both false and true:

stores.sort { Int($0.flagship ?? 2) < Int($1.flagship ?? 2) }

You can use the same pattern to make nil compare the same as true or the same as false. It's up to you.

like image 34
Kurt Revis Avatar answered Nov 12 '22 00:11

Kurt Revis


Here's another approach.

You can use flatMap which will remove nil objects and unwrap those that are present. Then, the force unwrap will be safe to sort:

let flagshipStores = stores.flatMap({ return $0.flagship ? $0 : nil }).sort {
    $0.flagship! && !$1.flagship!
}

This will remove stores with a nil flagship from the array.

like image 5
Aaron Brager Avatar answered Nov 11 '22 22:11

Aaron Brager


How about:

$0.flagship == true && $1.flagship != true

The left side will succeed if the value is not nil and is true, the right side will succeed if the value is either nil or false.

like image 2
Daniel Hall Avatar answered Nov 11 '22 22:11

Daniel Hall