rubyのflat_mapをちゃんと理解した

2019年の最初だし、ブログでも書いてみようという試み。

事の発端のツイート

この例は「flat_map使っているし、flatten要らないよね」って意図だったけど、@kamipoさんや@hanachin_さんからbarがネストした配列を返すときは必要というリプライを頂いた。

flat_mapよく分からなくなったので試した

実際に試してみて、flat_mapがmap+flatten(1)相当だと理解できた。

require 'rspec'

RSpec.describe 'flat_map' do
  it 'mapしてflatten(1)と同じ' do
    nums = [1, 2, 3]
    # [num, [num*2, num**2]] になる配列
    expected = [1, [2, 1], 2, [4, 4], 3, [6, 9]]

    x = nums.map { |n| [n, [n * 2, n**2]] }.flatten(1)
    expect(x).to eq expected

    y = nums.flat_map { |n| [n, [n * 2, n**2]] }
    expect(y).to eq expected

    z = nums.map { |n| [n, [n * 2, n**2]] }.flatten
    expect(z).to eq expected
    # Failure/Error: expect(z).to eq expected
    #
    #   expected: [1, [2, 1], 2, [4, 4], 3, [6, 9]]
    #        got: [1, 2, 1, 2, 4, 4, 3, 6, 9]
  end
end

RSpec::Core::Runner.invoke

まとめ

flat_map使っても、制限なしにflatになるわけではない。

参考ページ