29027


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

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

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

[code]

        //来店日時を新しい順でソート
        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
    
[/code]


CC BY-SA 3.0
2016-09-20T23:06:20.193
29011
2016-09-21T10:45:29.253
2016-09-21T00:06:30.267
18443
18443
question
swift
配列のソート結果を他の配列の並べ替えにも使いたい


配列のソートの結果を他の配列のソートに反映するのはリレーション情報が足りないと思うので、名前、予約人数、日付でクラスを作り、そのクラスの日付に対してソートするのはいかがでしょうか？

例えばですが、クラスを作る例だとこうなります。

[code]

    import Cocoa
    
    // Definition
    class Customer {
        var name: String = ""
        var numOfPeople: Int
        var date : String
    
        init (name: String, numOfPeople: Int, date: String) {
            self.name = name
            self.numOfPeople = numOfPeople
            self.date = date
        } // end init
    } // end class definition of Customer
    
    let person1 = Customer(name: "山田", numOfPeople: 2, date: "1012")
    let person2 = Customer(name: "鈴木", numOfPeople: 4, date: "1010")
    let person3 = Customer(name: "坂本", numOfPeople: 3, date: "1011")
    
    var customers = [person1, person2, person3];
    let sortedCustormers = customers.sorted(by: {$1.date > $0.date})
    
    for person: Customer in sortedCustormers {
        print(person.date, person.name, person.numOfPeople)
    }
    
[/code]

こうすると、結果は

[code]

    1010 鈴木 4
    1011 坂本 3
    1012 山田 2
    
[/code]

の様に日付の早い順になり、他の要素も追従してソートされます。  
これをラベルにセットしたい時は、

[code]

    cell!.number.text = sortedCustomer[indexPath.row].name
    
[/code]

の様に取り扱えば良いと思います。  
こういう自前のクラスをUsersDefaultへ保存・取り出す時にこそ、`setObject(_
,forKey:)`と`objectForKey`を使えば良いと思います。


CC BY-SA 3.0
2016-09-21T05:35:40.033
29019
2016-09-21T06:31:32.077
2016-09-21T06:31:32.077
14745
14745
29011
answer


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

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

[code]

    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`への代入を想定
    }
    
[/code]

**出力**

[code]

    [(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
    
[/code]

* * *

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

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


CC BY-SA 3.0
2016-09-21T10:45:29.253
29027
2016-09-21T10:45:29.253
13972
29011
answer