LoginSignup
3
1

rubyの個人的推しメソッド take_while を使ってみよう

Last updated at Posted at 2024-03-26

rubyの組み込みメソッド一覧を見ていると
「こんなメソッドがあったんだ!」という
マイナー(個人の感想です)なメソッドを見つけることがありますよね。
痒いところに手が届くような、豊富なメソッドがrubyにはありますが
そんなメソッドの中、個人的推しメソッドであるtake_whileを紹介します。

take_whileの機能

take_whileは、Enumerableモジュールのメソッドです。

Enumerableオブジェクトの要素を順に評価し、
falseになった最初の要素の、手前の要素までを配列で返却します

こんな時につかおう!

image.png

例えば、シャッフルしたデッキのトップからカードを順に引いていき、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"]

こちらも、うまく使ってあげればシンプルな実装ができるシーンがありそうですね :sparkles:

ところで、なんでこのメソッドが推しなの?

深い理由はありません!!!

強いて言うなら、eachメソッドで結構簡単に代替できるのに
わざわざ用意されているというところに、rubyの気が利く感じというか…
そんなマインドを感じるからかもしれません。

あなたの推しメソッドはなんですか?
是非Qiitaに記事を作成して教えてください😆

参考

Rubyリファレンスマニュアル

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1