LoginSignup
13
13

More than 5 years have passed since last update.

[Ruby] 配列の各要素を2連続させるイディオム

Posted at

問題

こんな配列を、

[1, 2, 3]

こうしたい。

[1, 1, 2, 2, 3, 3]

どういう書き方があるんだろう?

・・・という話題が某所で挙がったので、いくつかイディオムを考えてみました。

#map

よくあるアイデアはmapを使う方法かもしれません。

[1, 2, 3].map{|v| [v, v]}.flatten #=> [1, 1, 2, 2, 3, 3]

しかし、もっといいメソッドがあります。

#flat_map

map + flattenするなら、その名もズバリ、flat_mapというメソッドが使えます。

[1, 2, 3].flat_map{|v| [v, v]} #=> [1, 1, 2, 2, 3, 3]

#zip

しかし、個人的に一番好きなのはzipを使って宣言的に書く方法です。

array = [1, 2, 3]
array.zip(array).flatten #=> [1, 1, 2, 2, 3, 3]

変数への格納とflattenをなくせるともっとカッコいいんですが。

RSpecで確認する

ちゃんとテストも書いて確認しましょうね~。

describe 'duplicate each item' do
  let(:array) { [1, 2, 3] }
  shared_examples 'duplicate each item' do
    it { should eq [1, 1, 2, 2, 3, 3] }
  end
  describe 'use map' do
    subject { array.map{|v| [v, v]}.flatten }
    it_behaves_like 'duplicate each item'
  end
  describe 'use flat_map' do
    subject { array.flat_map{|v| [v, v]} }
    it_behaves_like 'duplicate each item'
  end
  describe 'use zip' do
    subject { array.zip(array).flatten }
    it_behaves_like 'duplicate each item'
  end
end

まとめ

他にもいろいろやり方はあると思いますが、上の3つぐらいが一番シンプルかな~と思います。
「もっと短くてクールなイディオムがあるぜ!」という方は、ぜひコメントをお願いします~。

あわせて読みたい

13
13
4

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
13
13