rubyの組み込みメソッド一覧を見ていると
「こんなメソッドがあったんだ!」という
マイナー(個人の感想です)なメソッドを見つけることがありますよね。
痒いところに手が届くような、豊富なメソッドがrubyにはありますが
そんなメソッドの中、個人的推しメソッドであるtake_while
を紹介します。
take_whileの機能
take_while
は、Enumerableモジュールのメソッドです。
Enumerableオブジェクトの要素を順に評価し、
falseになった最初の要素の、手前の要素までを配列で返却します
こんな時につかおう!
例えば、シャッフルしたデッキのトップからカードを順に引いていき、JOKERが出るまで手札に加えるような処理を想定します。
deck = ['♠️2', '♦️5', '♠️3', '❤️7', 'JOKER', '♦️8', '❤️K', '♣️A']
hand_cards = deck.take_while { |card| card != 'JOKER' }
#=> ["♠️2", "♦️5", "♠️3", "❤️7"]
このように、take_while
を使用することで簡単に実装できました。
同様の結果を得る処理
以下のようなコードが使われている箇所があれば、take_while
に代替できるかもしれません。
deck = ['♠️2', '♦️5', '♠️3', '❤️7', 'JOKER', '♦️8', '❤️K', '♣️A']
# eachを使用
hand_cards = []
deck.each do |card|
break hand_cards if card == 'JOKER'
hand_cards << card
end
#=> ["♠️2", "♦️5", "♠️3", "❤️7"]
# each_with_objectを使用
hand_cards = deck.each_with_object([]) do |card, arr|
break arr if card == 'JOKER'
arr << card
end
#=> ["♠️2", "♦️5", "♠️3", "❤️7"]
逆の効果を持つdrop_whileもあるぞ!
take_while
とは逆に
Enumerableオブジェクトの要素を順に評価し、
falseになった最初の要素"以降"の要素を配列で返却する
deop_while
というメソッドも用意されています。
deck = ['♠️2', '♦️5', '♠️3', '❤️7', 'JOKER', '♦️8', '❤️K', '♣️A']
# JOKERを引くまでのカードは捨て、JOKER以降のカードを取得する
deck.drop_while { |card| card != 'JOKER' }
#=> ["JOKER", "♦️8", "❤️K", "♣️A"]
こちらも、うまく使ってあげればシンプルな実装ができるシーンがありそうですね
ところで、なんでこのメソッドが推しなの?
深い理由はありません!!!
強いて言うなら、eachメソッドで結構簡単に代替できるのに
わざわざ用意されているというところに、rubyの気が利く感じというか…
そんなマインドを感じるからかもしれません。
あなたの推しメソッドはなんですか?
是非Qiitaに記事を作成して教えてください😆
参考
Rubyリファレンスマニュアル