LoginSignup
17
16

More than 5 years have passed since last update.

[Swift3] 配列を複数の条件で並び替える(ソート)

Last updated at Posted at 2017-04-29

はじめに

アプリ内でデータベースを利用していないときに、
配列をソートするサンプルです。

例えば、
リリース日の降順、いいね数の降順にソートしたいときに活用します。

NSSortDescriptorで検索条件を指定して、
NSMutableArrayのsortUsingDescriptorsを利用してソートする方法がありますが、
SwiftでNSMutableArray型をあまり利用したくないため、
Array型の配列をソートするサンプルをご紹介します。

サンプル

1. ソート条件を指定するためのデータを用意する

    typealias SortDescriptor<Value> = (Value, Value) -> Bool

2. 複数のソート条件を結合するメソッドを用意する

    func combine<Value>(sortDescriptors: [SortDescriptor<Value>]) -> SortDescriptor<Value> {

        return { lhs, rhs in
            for isOrderedBefore in sortDescriptors {
                if isOrderedBefore(lhs,rhs) { return true }
                if isOrderedBefore(rhs,lhs) { return false }
            }
            return false
        }
    }

3. 使い方

3.1. リリース日といいね数を管理するクラスを定義する

struct Item {
    var releaseDate = ""
    var like = 0
}

3.2. 配列にデータを登録する

    let items: [Item] = [
        Item(releaseDate:"2016-01-01 01:01", like: 100),
        Item(releaseDate:"2017-10-10 10:10", like: 100),
        Item(releaseDate:"2017-10-10 10:10", like: 120),
        Item(releaseDate:"2017-10-10 10:10", like: 80),
        Item(releaseDate:"2017-10-10 12:10", like: 80),
        Item(releaseDate:"2017-09-10 10:10", like: 100),
        Item(releaseDate:"2017-01-01 10:10", like: 100)
    ]

3.3. ソート条件を指定する

リリース日の降順、いいね数の降順に指定する例です。

    let sortedByReleaseDate: SortDescriptor<Item> = { $0.releaseDate > $1.releaseDate }
    let sortedBylike: SortDescriptor<Item> = { $0.like > $1.like }

3.4. 複数のソート条件を結合する

    let combined: SortDescriptor<Item> = combine(
        sortDescriptors: [sortedByReleaseDate,sortedBylike]
    )

3.5. ソートする

   let result = items.sorted(by: combined)

3.6. 結果を確認する

    _ = result.map {
        print($0)
    }

出力結果は、下記のとおりです。
リリース日の降順、いいね数の降順に並びました。

Item(releaseDate: "2017-10-10 12:10", like: 80)
Item(releaseDate: "2017-10-10 10:10", like: 120)
Item(releaseDate: "2017-10-10 10:10", like: 100)
Item(releaseDate: "2017-10-10 10:10", like: 80)
Item(releaseDate: "2017-09-10 10:10", like: 100)
Item(releaseDate: "2017-01-01 10:10", like: 100)
Item(releaseDate: "2016-01-01 01:01", like: 100)

まとめ

便利なメソッドがNS○○クラスにしか提供されていないことはよくありますね。
そのために、データ型を変更するのは嫌ですね。

Extensionで復活させる方法もありますが、
今回は、下記のサイトにまとめられていたため、
共有の意味で記事を書かせて頂きました。

参考記事

Sort Description in Swift

17
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
16