【Swift】多次元配列を昇順でソート
どうも、ねこきち(@nekokichi1_yos2)です。
Int型の多次元配列をソートする方法が載ってなかったので、備忘録として記載。
バブルソート、というアルゴリズムを使うと、簡単に実装できました。
今回のバブルソートを実装する際、下記を参考にさせていただきました。
(donguriさん、ありがとうございました。)
↓
解説
今回使用する配列は、Int型の2次元配列です。
var array = [[2020,9,5],[2020,12,5],[2019,11,9],[2019,11,1],[2019,1,13],[2010,5,13],[2020,2,20],[2010,6,8]]
([年、月、日]の配列)
仕組みは、
- 隣り合う要素を比較
- 大小関係が成り立つかを調べる
- 成り立てば両方を入れ替える
- 1周して1度も成り立たなくなれば、終了
です。
repeat-while文は、条件式(flag)が
- trueなら継続
- falseなら抜ける
で、ループ度に条件式はfalseにリセットされ、入れ替えが起こればtrueになるのでまた1つ目の要素から大小関係の照合が行われ、1周ループしてfalseのままなら抜けます。
strideは、指定範囲(from~to)を指定数字刻み(by)でループするもので、今回の場合、
- 1,2,3,4,5,6,7
の数字がiに返されます。
(指定範囲の末尾は、to - 1、で、最後の数字は含まれません。)
swapAtは、引数に指定した配列内にある2つの要素を入れ替えます。
年のソート
stirdeにより、for文のiには1~7が入り、
- i番目
- i-1番目
の2つを比較します。
最初は0番目と1番目を比較し、最後は6番目と7番目を比較。
これで、年の昇順ソートが完成。
月のソート
もし月のソートだけ行えば、月を基準にソートされるので、年の昇順が崩れてしまいます。
ですから、年の順番を保ちつつ、月をソートする場合、年の条件式も加える必要があります。
既に年は昇順に並んでるので、後は比較対象である2つの要素が同じ年?、であるかを確認するだけです。
日のソート
既に年と月の昇順は成り立ってるので、比較対象が同じ年/月であるかを確かめればOKです。
ソースコード
//ループ判定 var flag = false var array = [[2020,9,5],[2020,12,5],[2019,11,9],[2019,11,1],[2019,1,13],[2010,5,13],[2020,2,20],[2010,6,8]] //年をソート func sortYear() { repeat { flag = false for i in stride(from: 1, to: array.count, by: 1) { if array[i][0] < array[i-1][0] { array.swapAt((i-1), i) flag = true } } } while flag } //月をソート func sortMonth() { repeat { flag = false for i in stride(from: 1, to: array.count, by: 1) { if array[i][0] == array[i-1][0] { if array[i][1] < array[i-1][1] { array.swapAt((i-1), i) flag = true } } } } while flag } //日をソート func sortDay() { repeat { flag = false for i in stride(from: 1, to: array.count, by: 1) { if array[i][0] == array[i-1][0] { if array[i][1] == array[i-1][1] { if array[i][2] < array[i-1][2] { array.swapAt((i-1), i) flag = true } } } } } while flag }
結果
//年のソート [[2010, 5, 13], [2010, 6, 8], [2019, 11, 9], [2019, 11, 1], [2019, 1, 13], [2020, 9, 5], [2020, 12, 5], [2020, 2, 20]] //年、月のソート [[2010, 5, 13], [2010, 6, 8], [2019, 1, 13], [2019, 11, 9], [2019, 11, 1], [2020, 2, 20], [2020, 9, 5], [2020, 12, 5]] //年、月、日のソート [[2010, 5, 13], [2010, 6, 8], [2019, 1, 13], [2019, 11, 1], [2019, 11, 9], [2020, 2, 20], [2020, 9, 5], [2020, 12, 5]]