Search code examples
iosarraysswiftsortingnsarray

How to sort in swift by a BOOL without changing the original order in main array?


I have one array of models which has 2 properties:

1. title (String)

2. isSelected (Bool)

I want to sort them based on the isSelected property such that it does relatively to the sequence of source array. For example, if all are FALSE or TRUE then there should be same output after ordering.

But if I use following method, it alters the original sorting after ordering them based on that BOOL property.

someArray = array.sort { $0.selected && !$1.selected }

What should I do to retain original sequence?

EDIT 1

Sorting order of title does not come in picture. May be server send me 4 objects having title Z,Y,P,A. So if all are false and once I sort, it should be like Z false,Y false, P false, A false.


Solution

  • Instead of sorting, you can do that more effectively using a filter operation:

    let newArray = array.filter { $0.selected } + array.filter { !$0.selected }
    

    Unfortunately, Array.sorted does not guarantee a stable sort, therefore you cannot just sort by one property and expect the original sort to be kept.

    You can implement stable sort easily though (e.g. https://stackoverflow.com/a/50545761/669586)

    Then you can simply use:

    let newArray = array.stableSorted {    
       let numeric1 = $0.selected ? 0 : 1
       let numeric2 = $1.selected ? 0 : 1
    
       return numeric1 <= numeric2
    }
    

    or

    let newArray = array.stableSorted {
       return $0.selected == $1.selected || $0.selected
    }