hene

hene.dev

いろいろ操作して Hash を作ってみる

いろいろ操作して Hash を作ってみる

Hash を作ろうとしたときに色々なやり方があることを知りました。

each

一番最初に思いついた内容です。

# each_sample.rb

class EachSample
  attr_reader :a, :b, :c

  def initialize(*words)
    @a, @b, @c = *words
  end

  def hash_abc
    hash = {}
    %w[a b c].each do |word|
      hash[word] = send(word)
    end
    hash
  end
end

each_sample = EachSample.new('ruby', 'vue', 'go')
p each_sample.hash_abc
$ ruby each_sample.rb
{"a"=>"ruby", "b"=>"vue", "c"=>"go"}

下記部分を消したくなりました。

  def hash_abc
    hash = {} # 消したい
    %w[a b c].each do |word|
      hash[word] = send(word)
    end
    hash # 消したい
  end

reduce(inject)

reduce(inject)を使うと、each より少し短くかけます。

# reduce_sample.rb

class ReduceSample
  attr_reader :a, :b, :c

  def initialize(*words)
    @a, @b, @c = *words
  end

  def hash_abc
    %w[a b c].reduce({}) do |hash, word|
      hash[word] = send(word)
      hash
    end
  end
end

reduce_sample = ReduceSample.new('ruby', 'vue', 'go')
p reduce_sample.hash_abc
$ ruby reduce_sample.rb
{"a"=>"ruby", "b"=>"vue", "c"=>"go"}

hash を消したい・・・

  def hash_abc
    %w[a b c].reduce({}) do |hash, word|
      hash[word] = send(word)
      hash # 消したい
    end
  end

each_with_object

each_with_object を使うと、reduce より少し短くかけます。

# each_with_object_sample.rb

class EachWithObjectSample
  attr_reader :a, :b, :c

  def initialize(*words)
    @a, @b, @c = *words
  end

  def hash_abc
    %w[a b c].each_with_object({}) do |word, hash|
      hash[word] = send(word)
    end
  end
end

each_with_object_sample = EachWithObjectSample.new('ruby', 'vue', 'go')
p each_with_object_sample.hash_abc
$ ruby each_with_object.rb
{"a"=>"ruby", "b"=>"vue", "c"=>"go"}

スッキリしました。

  def hash_abc
    %w[a b c].each_with_object({}) do |word, hash|
      hash[word] = send(word)
    end
  end

まとめ

すべて同じ結果が返ってきますが、短くわかりやすいコードを書いていきたいです。

# hash_sample.rb

class HashSample
  attr_reader :a, :b, :c

  def initialize(*words)
    @a, @b, @c = *words
  end

  def each_sample
    hash = {}
    %w[a b c].each do |word|
      hash[word] = send(word)
    end
    hash
  end

  def reduce_sample
    %w[a b c].reduce({}) do |hash, word|
      hash[word] = send(word)
      hash
    end
  end

  def each_with_object_sample
    %w[a b c].each_with_object({}) do |word, hash|
      hash[word] = send(word)
    end
  end
end

hash_sample = HashSample.new('ruby', 'vue', 'go')
puts "each: #{hash_sample.each_sample}"
puts "reduce: #{hash_sample.reduce_sample}"
puts "each_with_object_sample: #{hash_sample.each_with_object_sample}"
$ ruby hash_sample.rb
each: {"a"=>"ruby", "b"=>"vue", "c"=>"go"}
reduce: {"a"=>"ruby", "b"=>"vue", "c"=>"go"}
each_with_object_sample: {"a"=>"ruby", "b"=>"vue", "c"=>"go"}

参考

関連記事