配列、ハッシュを半分に分ける
Rubyを書いていて配列やハッシュを綺麗に半分に分けたいなってときありますよね?少なくともぼくはあったし、今この記事を見ているあなたもそう思ってるのかもしれません。 イメージとしてはこんな感じです。
[1, 2, 3, 4] => [[1, 2], [3, 4]] ["Yamada" => 34, "Katou" => 28, "Endou" => 18, "Matsumoto" => 25] => ["first_half" => ["Yamada" => 34, "Katou" => 28], "second_half" =>["Endou" => 18, "Matsumoto" => 25]]
配列
まず配列についてですが、もっといいやり方がある気もするのですが、単純な方法で実装しています。...と..
今回は要素が偶数でちょうど半分に割ることを想定しているので、奇数の場合はfirst_halfの要素が1つ多くなってしまいますが、そこはオプションを持たしたりということはしていません。
class HalfArray def self.half_array(array) first_half = array.slice(0...array.size/2) second_half = array.slice((array.size/2)..array.size) halfed_array = [first_half, second_half] end end sample_array = [1, 2, 3, 4] HalfArray.half_array(sample_array) => [[1, 2], [3, 4]]
でせっかくなのでArrayクラスを拡張した形に変えてみます。
class Array def half first_half = self.slice(0...self.size/2) second_half = self.slice((self.size/2)..self.size) halfed_array = [first_half, second_half] end end sample = [1,2,3,4] sample.half => [[1, 2], [3, 4]]
うまくいきましたね!
ハッシュ
続いてハッシュです。これについては一旦Arrayにして半分に割りもう一度ハッシュに戻すという、配列以上にもっといいやり方がありそうな気がするやり方をしてます笑
class HalfHash def self.half_hash(hash, first_key, second_key) first_half = Hash[hash.to_a.slice(0...(hash.size/2))] second_half = Hash[hash.to_a.slice((hash.size/2)..hash.size)] halfed_hash = {first_key => first_half, second_key => second_half} end end sample_hash = {"Yamada" => 34, "Katou" => 28, "Endou" => 18, "Matsumoto" => 25} result = HalfHash.half_hash(sample_hash, "sample_first", "second_first") => {"sample_first"=>{"Yamada"=>34, "Katou"=>28}, "second_first"=>{"Endou"=>18, "Matsumoto"=>25}}
配列と同様Hashクラスを拡張します
class Hash def half (first_key, second_key) first_half = Hash[self.to_a[0..(self.size/2 - 1)]] second_half = Hash[self.to_a[(self.size/2)..self.size]] halfed_hash = {first_key => first_half, second_key => second_half} end end sample_hash = {"Yamada" => 34, "Katou" => 28, "Endou" => 18, "Matsumoto" => 25} sample_hash.half("first_half", "second_half") => {"first_half"=>{"Yamada"=>34, "Katou"=>28}, "second_half"=>{"Endou"=>18, "Matsumoto"=>25}}
配列とハッシュの処理をまとめる
で最後に配列とハッシュの処理がかなり重複しているのでDRYな感じにしてしましましょう。
class Array def half first_half = self.slice(0...self.size/2) second_half = self.slice((self.size/2)..self.size) halfed_array = [first_half, second_half] end end class Hash def half (first_key, second_key) first_half = Hash[self.to_a.half[0]] #ここでArrayのhalfを使う second_half = Hash[self.to_a.half[1]] #ここも halfed_hash = {first_key => first_half, second_key => second_half} end end sample = [1,2,3,4] sample.half => [[1, 2], [3, 4]] sample_hash = {"Yamada" => 34, "Katou" => 28, "Endou" => 18, "Matsumoto" => 25} sample_hash.half("first_half", "second_half") => {"first_half"=>{"Yamada"=>34, "Katou"=>28}, "second_half"=>{"Endou"=>18, "Matsumoto"=>25}}
追記
Railsではin_groups_ofというメソッドがあるので、それを使うのが良いです。
sample_even = [1, 2, 3, 4] sample.in_groups_of(sample.size/2) => [[1, 2], [3, 4]] sample_odd = [1, 2, 3, 4, 5, 6, 7] # 奇数の場合はオプションにfalseをつけないと足りない分の要素1つがnilで埋まります。 sample.in_groups_of(sample.size/2 + 1, false) => [[1, 2, 3, 4], [5, 6, 7]]