23
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RubyAdvent Calendar 2016

Day 20

どう書くで見る ruby の便利機能

Last updated at Posted at 2016-12-24

この記事は Ruby Advent Calendar 2016の20日目の記事のつもりで書いている。

Advent Calendar というものに参加するのは初めてなので緊張している。

実務ではあまり ruby を使っていないので、私は自分が主催しているどう書く( https://yhpg.doorkeeper.jp/ )での ruby の使われ方を書こうと思う。

思いついた順なので、ごちゃごちゃするけど気にしない方向で。

Array#transpose

行列ではないものをtransposeできる言語が他にあるかどうか知らないんだけど、transposeは便利。

x方向で処理するプログラムだけを用意しておいて、y方向の処理は、データを transpose したものを渡すことで済ますとか。

あるいは、平面的なものを回転するときに役に立つ。

2次元配列をreverseしてからtransposeすると時計回りに、transposeしてからreverseすると反時計回りに回せる。

Object#tap〜break

メソッドチェインをしていくなかで、パスしていくオブジェクトを $x$ から $f(x)$ に変更したい場合に使う。

foo.略{略}.略{略}.tap{ |x| break f(x) }.略{略}

のような感じ。

標準で存在して然るべきメソッドだと思う。

Integer#divmod

除算の結果の商と剰余がいっぺんに手に入る。

123.divmod(100) #=> [1, 23]

一次元的に表現された平面から座標を取るときに活躍する。
配列でもらえるので、そのままメソッドチェインに流し込んだりするのも便利。

Array#minmax

min と max がいっぺんに手に入る。

"helloworld".chars.minmax # => ["d", "w"]

こんな感じ。
これもそのままメソッドチェインに流すことが出来る。便利。

String#ord Integer#chr

"a"〜"z" を 0〜25 などに変換する必要がある場面は多いので、n=c.ord-?a.ord のような計算はよく出てくる。
逆変換は、c=(n+?a.ord).chr

Integer#[ ]

Integerには123[4] のように呼べるメソッドがあって、トラブルの原因になりやすいような気もするけど、ビット演算が簡単にできるのはとても便利。
先の例は、( (123 & (1<<4))==0 )? 0 : 1 と同じなので、

123[4] # => 1

ちなみに、Integer#[ ]= はない。

Array#& と Array#|

[1,1,2,3,4,4] & [3,4,4,5] # => [3, 4]
[1,1,2,3,4,4] | [3,4,4,5] # => [1, 2, 3, 4, 5]

のように、Array#uniq の処理を含んでいることに注意。というか、そこもわかっていると便利。

Math.log2 と Math.cbrt

Math.log2 は、 $\frac{\ln(x)}{\ln(2)}$ の計算をする。何に使うのかというと、場合の数。
なので、Math.log2(x).ceil のような感じで、ceilfloor とセットで使うと思う。

Math.log(x)/Math.log(2) のような計算と違って、誤差が出にくい。

Math.log(2**29)/Math.log(2) #=> 29.000000000000004
Math.log2(2**29) #=> 29.0

そういえば、三乗根の Math.cbrt が便利だったこともある:

64**(1.0/3) # => 3.9999999999999996
Math.cbrt(64) #=> 4.0

こちらも誤差が出にくい。

オープンクラスの悪用

たとえば、平面上の座標を配列で表現しようと思うとする。
そんなとき、

class Array
  def x; self[0]; end
  def y; self[1]; end
end

のような悪用をすると結構便利。仕事だと許されないと思うけど、どう書くならアリだと思う。

Array#combination と仲間たち

Array には、combination, permutation, repeated_combination, repeated_permutation という4つの便利メソッドがある。

それぞれ名前のとおりなんだけど、実行結果は以下の通り:

[1,2,3].combination(2).to_a
#=> [[1, 2], [1, 3], [2, 3]]
[1,2,3].permutation(2).to_a
#=> [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
[1,2,3].repeated_combination(2).to_a
#=> [[1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 3]]
[1,2,3].repeated_permutation(2).to_a
#=> [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]

実際に書こうとすると再帰だったりして面倒になるので、これがあるのは本当に助かる。というか、出題者としては困るぐらい便利。

【宣伝】

現在、私が主催するオフラインリアルタイムどう書くでは

の参加者を募集しています。

23
25
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
23
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?