ドキュメントをみたら、sort.Reverse()
という関数があった。お、これはPythonの順番を逆転する例のやつかな、と思って使ってみた。
a: l = []string{"a", "b", "c"} // lはLess, Len, Swapが定義されたインタフェース
sort.Reverse(a)
log.Println(a)
// "a", "b", "c"
// 変わってない!
え、何も仕事してないじゃん、と思ってコードを見てみたら・・・
つまり、sort.Interface
を実装してからソートしていたもうはるか思い出せないぐらい過去の時代のためのコードで、単にLess()
メソッドのtrue/falseを逆転させた別のインタフェースを作っているだけで、ここからソートしてあげないとソートはされない
a: l = []string{"a", "b", "c"}
sort.Sort(sort.Reverse(a))
log.Println(a)
// "c", "b", "a"
// 変わった!
まあ、今時ならsort.Slice()
使えばイチコロですね。添字だけみてソートすればOK。こちらの方が簡単ですね。
要素数が少なかったらそれっぽく動いているように見えていましたがダメでした。一回順番変わっちゃったあとは元のインデックスを保持しないので同じ要素が2回以降評価されるとダメでした。
なので、入れ替えるときは地道に入れ替えるのが一番早道ですね。
l := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
for i := 0; i < len(l) / 2; i++ {
l[i], l[len(l) - i - 1] = l[len(l) - i - 1], l[i]
}
fmt.Println(l)
// [15 14 13 12 11 10 9 8 7 6 5 4 3 2 1]
少ないときだけうまくいった理由をkaoriyaさんがコメントしてくださいました。ありがとうございます。
最後のSliceを使ったReverseの実装なんですけど、要素が7個以上になるとうまく動きません。添え字比較だと比較結果が値に対して安定しないので。
— MURAOKA Taro (@kaoriya) September 16, 2020
6個以下のときにうまくいくのはsort.Sliceの最適化でinsertionSortだけになってるからだと思われます。https://t.co/QtLt7Owv1X