このようなハッシュとラムダの違いは何ですか?
ラムダとハッシュには共通点はありません。あなたの質問は、次のように尋ねています。
メソッドと配列の違いは何ですか?
ハッシュが存在しないキーのデフォルト値を指定できるというだけです:
h = Hash.new(10)
h["a"] = 2
puts h["a"]
puts h["b"]
--output:--
2
10
ハッシュは、デフォルト値を動的に指定する方法も提供します: ブロックを提供できます。次に例を示します。
h = Hash.new do |h, key|
h[key] = key.length
end
puts h['hello']
puts h['hi']
p h
--output:--
5
2
{"hello"=>5, "hi"=>2}
存在しないキーにアクセスすると、ブロックが呼び出され、ブロックは必要なことを実行できます。そのため、誰かが巧妙に、ハッシュを作成し、フィボナッチ数を計算するデフォルト値を指定できることを発見しました。仕組みは次のとおりです。
h = Hash.new do |h, key|
if key < 2
h[key] = key
else
h[key] = h[key-1] + h[key-2]
end
end
これにより、キーや値のないハッシュであるハッシュ h が作成されます。次に書く場合:
puts h[3]
...3 は存在しないキーなので、ブロックは引数 h と 3 で呼び出されます。ブロック内の else 句が実行され、次のようになります。
h[3-1] + h[3-2]
また:
h[2] + h[1]
しかし、そのステートメントを評価するには、ruby は最初に h[2] を評価する必要があります。しかし、Ruby がハッシュで h[2] を検索すると、キー 2 は存在しないキーであるため、ブロックは引数 h と 2 で呼び出され、次のようになります。
(h[2-1] + h[2-2]) + h[1]
また:
(h[1] + h[0]) + h[1]
そのステートメントを評価するには、最初の h[1] を評価する必要があります。Ruby がハッシュで h[1] を検索しようとすると、1 は存在しないキーであるため、h と 1 の引数でブロックが呼び出されます。今度は if 分岐が実行され、次のことが起こります。
h[1] = 1
h[1] の値として 1 が返され、次のようになります。
(1 + h[0]) + h[1]
次に ruby は h[0] を検索し、0 は存在しないキーであるため、ブロックは引数 h と 0 で呼び出され、if 節が実行されてこれが行われます。
h[0] = 0
h[0] の値として 0 が返され、次のようになります。
(1 + 0) + h[1]
次に、ruby はハッシュで h[1] を検索します。今回はキー 1 が存在し、値が 1 であるため、次のようになります。
(1 + 0) + 1
そしてそれは 2 に等しいので、h[3] は 2 に等しく設定されます。h[3] を呼び出すと、次の出力が得られます。
puts h[3]
p h
--output:--
2
{1=>1, 0=>0, 2=>1, 3=>2}
ご覧のとおり、以前の計算はすべてハッシュにキャッシュされています。つまり、他のフィボナッチ数に対してこれらの計算を再度実行する必要はありません。