配列のソート結果を他の配列の並べ替えにも使いたい

投稿者: Anonymous

予約管理アプリのようなものをつくっています。

それぞれ別の配列に格納された1.予約者名、2.来店日時、3.人数を「来店日時が新しい順」で全て並べ替えたいです。

来店日時をソートした結果(以下のtimeSort)と順番が揃うように、予約者名と人数をソートしたいのですが、どのような手法が考えられますでしょうか。

    //来店日時を新しい順でソート
    let time = ud.objectForKey("time") as? [String]
    let timeSort = time!.sort { $1 < $0 }
    cell!.time.text = timeSort[indexPath.row]

    //予約者名
    let name  = ud.arrayForKey("name")
    cell!.name.text = name![indexPath.row] as! String

    //予約人数
    let number  = ud.arrayForKey("number")
    cell!.number.text = name![indexPath.row] as! Int

解決

方向性としてはЧайкаさんの回答で示されているようにCustomerのようなデータ型(私ならstructを選択するかも知れませんが)を定義してしまう、と言うのが確実で定石と言えるでしょう。

ここでは、Swiftでの配列の取り扱い方の練習と言った意味でenumerate()を使った別解を紹介しておきます。Playground上で動作確認出来るようにしてありますので、いろいろいじって動作を確かめてみてください。

import Foundation

//来店日時
let time: [String] = ["2016-10-01 18:00", "2016-10-02 20:00", "2016-10-01 20:00"]
//予約者名
let name: [String] = ["Jack", "Ace", "Taro"]
//予約人数
let number: [Int] = [4, 5, 6]

//来店日時にインデックスを付加したタプルを来店日時の新しい順でソート
// `timeAndIndexSorted`は、元の`time`のindex番号とそのindexの要素がペアで並ぶ`[(index: Int, element: String)]`型の配列になる
let timeAndIndexSorted = time.enumerate().sort { $1.element < $0.element }
print(timeAndIndexSorted)

for indexPathRow in 0..<time.count {
    //並べ替えた後の並びから元のindex番号を取り出す
    let originalIndex = timeAndIndexSorted[indexPathRow].index

    //`time`自体は並び替えていないがindex番号が正しく変換されている
    print(time[originalIndex], terminator: ",")

    print(name[originalIndex], terminator: ",")

    print(String(number[originalIndex])) //不要な`String()`で囲っているのは`cell!.number.text`への代入を想定
}

出力

[(1, "2016-10-02 20:00"), (2, "2016-10-01 20:00"), (0, "2016-10-01 18:00")]
2016-10-02 20:00,Ace,5
2016-10-01 20:00,Taro,6
2016-10-01 18:00,Jack,4

ご質問の内容には直接関係ありませんが、NSUserDefaultsは本来は「設定」画面にあるような各アプリに対するユーザの設定値を覚えておくことを想定して作られているクラスです。サンプルアプリや練習アプリと言うことでせいぜい数十件から数百件のデータを相手にする間は良いのですが、実際にApp Storeでのリリースを目指すようなアプリにするのであれば、NSArchiver(NSCoding)の使い方を覚えるなり、Core Dataもしくはサードパーティのデータフレームワークの採用を考えられた方が良いでしょう。

(平気でNSUserDefaultsにド大量の画像を保存しちゃう、なんて方もプロとしてやっておられたりしますが…)

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *