8

my object looks like :

object = [[section: "section1", order: "1"],
          [section: "section2", order: "1"],
          [section: "section1", order: "2"],
          [section: "section2", order: "2"]]

i want to sort it to have a result like :

[[section: "section1", order: "1"],
 [section: "section1", order: "2"],
 [section: "section2", order: "1"],
 [section: "section2", order: "2"]]

So i need to sort by section, and in each section by order.

That's what i'm doing :

  return Observable.from(realm
            .objects(Section.self).sorted(byProperty: "order", ascending: true)

The string "section.." is just for the example, it can be other thing so i can't just use the character to sort. I need a real priority on X string.

Makaille
  • 1,636
  • 2
  • 24
  • 41
  • 2
    Possible duplicate of [Swift - Sort array of objects with multiple criteria](http://stackoverflow.com/questions/37603960/swift-sort-array-of-objects-with-multiple-criteria) – Hamish Dec 19 '16 at 14:11
  • Seems you are using Realm. You'd better note it explicitly in your question. You can sort the result after creating a Swift Array as shown in some answers, but you can use [another `sorted` method](https://realm.io/docs/swift/latest/api/Classes/Results.html#/s:FC10RealmSwift7Results6sorteduRd__s8SequenceWd__8Iterator7Element_zVS_14SortDescriptorrFT2byqd___GS0_x_) of the `Result` class of Realm. which can take multiple `SortDescriptor`s. – OOPer Dec 19 '16 at 15:36

3 Answers3

7

To sort it by two factors you can do your custom logic with the "sorted" method : Here is an example that you can test in a playground.

    struct MyStruct {
    let section: String
    let order: String
}
let array = [MyStruct(section: "section1", order: "1"),
             MyStruct(section: "section2", order: "1"),
             MyStruct(section: "section1", order: "2"),
             MyStruct(section: "section2", order: "2")]

let sortedArray = array.sorted { (struct1, struct2) -> Bool in
    if (struct1.section != struct2.section) { // if it's not the same section sort by section
        return struct1.section < struct2.section
    } else { // if it the same section sort by order.
        return struct1.order < struct2.order
    }
}
print(sortedArray)
LastMove
  • 2,482
  • 1
  • 15
  • 25
2

Using Protocol

struct A {
    var firstName: String?
    var lastName: String?
}
protocol StringSortable {
    var property1: String {get}
    var property2: String {get}
}
extension A: StringSortable {
    var property1: String {
        return firstName ?? ""
    }
    var property2: String {
        return lastName ?? ""
    }
}
let array1 = [A(firstName: "Dan", lastName: "P2"), A(firstName: "Han", lastName: "P1"), A(firstName: "Dan", lastName: "P0"), A(firstName: "Han", lastName: "P8")]
let sortArray = array1.sorted {
    $0.property1 == $1.property1 ? $0.property2 < $1.property2 : $0.property1 < $1.property1
}
print(sortArray)

Dan P0

Dan P2

Han P1

Han P8

jpulikkottil
  • 666
  • 9
  • 24
0
let object = [["section": "section1", "order": "2"],
              ["section": "section2", "order": "2"],
              ["section": "section1", "order": "1"],
              ["section": "section2", "order": "1"],
              ["section": "section5", "order": "3"],
              ["section": "section6", "order": "1"],
              ["section": "section5", "order": "1"]]

     let Ordered = object.sorted{$0["order"]! < $1["order"]!  }

    let OrderedObjects = Ordered.sorted{$0["section"]! < $1["section"]!  }


    print(OrderedObjects)

 //[["section": "section1", "order": "1"], ["section": "section1", "order": "2"], ["section": "section2", "order": "1"], ["section": "section2", "order": "2"], ["section": "section5", "order": "1"], ["section": "section5", "order": "3"], ["section": "section6", "order": "1"]]
Rob
  • 2,649
  • 3
  • 27
  • 34