Rubyで配列をちょっとした条件でソートする
ある配列を独自の条件でソートするときもsort_byを使うとたいへん便利なのですが、書き方を失敗したときのエラーがわかりにくい場合があったので記事を書いてみます(5年くらい前もあれ、となっていたので)。
> (1..10).to_a.reverse
=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
たとえばこんな配列があります。これを昇順にソートするには単純にsortを使えばよい。
> (1..10).to_a.reverse.sort
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
これを偶数を先に並べるにはどうしましょう。
sort_byをつかうと簡単です。
> (1..10).to_a.reverse.sort_by{|i| i % 2}
=> [10, 8, 6, 4, 2, 9, 7, 5, 3, 1]
偶数が先だけれど、昇順にしたいときは、sort_byのなかを配列にするとできます。
> (1..10).to_a.reverse.sort_by{|i| [i % 2, i]}
=> [2, 4, 6, 8, 10, 1, 3, 5, 7, 9]
数字か文字列かで違うこともあまりないんですが、文字列で特定の文字を含む場合に先に並べたいときはどうでしょうか。同じようにやってみると・・・
> ["さばねこ","いぬ","しばいぬ","ねこ","とらねこ","あきたいぬ" ]
.sort_by{|animal| animal.include?("いぬ")}
ArgumentError: comparison of Array with Array failed
エラーが出ました。
配列と配列を比べていると失敗しています。ちょっとやっていることとわかりにくく、うまく説明できませんが、TrueやFalseといったBoolean同士を比較できないから、ではないかと思います(どなたかいい説明あれば教えてください・・・)
原因はさておき、どう解決するか。三項間演算子で数字にするのが簡単です。
> ["さばねこ","いぬ","しばいぬ","ねこ","とらねこ","あきたいぬ" ]
.sort_by{|animal| [animal.include?("いぬ") ? 0 : 1]}
=> ["いぬ", "しばいぬ", "あきたいぬ", "さばねこ", "ねこ", "とらねこ"]
いぬが先でそのなかで辞書順にするにはこうします
> ["さばねこ","いぬ","しばいぬ","ねこ","とらねこ","あきたいぬ" ]
.sort_by{|animal| [animal.include?("いぬ") ? 0 : 1, animal]}
=> ["あきたいぬ", "いぬ", "しばいぬ", "さばねこ", "とらねこ", "ねこ"]
はい。
簡単でした。多次元配列やHashの配列であっても同じような考え方でsort_byを使うと簡単です。配列に列挙していくのでなにを優先させるかもわかりやすいですね。
参考)
sort_by のドキュメントはこちら。
https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/sort_by.html
Author And Source
この問題について(Rubyで配列をちょっとした条件でソートする), 我々は、より多くの情報をここで見つけました https://qiita.com/daik/items/0913868fd5e74641b7a8著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .