Ruby 注入初始值是一个哈希值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9434162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 04:49:18  来源:igfitidea点击:

Ruby inject with initial being a hash

ruby

提问by Candide

Can any one tell me why the following:

任何人都可以告诉我为什么会出现以下情况:

['a', 'b'].inject({}) {|m,e| m[e] = e }

throws the error:

抛出错误:

IndexError: string not matched
        from (irb):11:in `[]='
        from (irb):11:in `block in irb_binding'
        from (irb):11:in `each'
        from (irb):11:in `inject'
        from (irb):11
        from C:/Ruby192/bin/irb:12:in `<main>'

whereas the following works?

而以下工作?

a = {}
a["str"] = "str"

回答by Rob Davis

Your block needs to return the accumulating hash:

您的区块需要返回累积的哈希值:

['a', 'b'].inject({}) {|m,e| m[e] = e; m }

Instead, it's returning the string 'a' after the first pass, which becomes min the next pass and you end up calling the string's []=method.

相反,它在第一次传递后返回字符串 'a',它m在下一次传递中变为并且您最终调用字符串的[]=方法。

回答by tokland

The block must return the accumulator (the hash), as @Rob said. Some alternatives:

正如@Rob 所说,该块必须返回累加器(哈希)。一些替代方案:

With Hash#update:

Hash#update

hash = ['a', 'b'].inject({}) { |m, e| m.update(e => e) }

With Enumerable#each_with_object:

Enumerable#each_with_object

hash = ['a', 'b'].each_with_object({}) { |e, m| m[e] = e }

With Hash#[]:

Hash#[]

hash = Hash[['a', 'b'].map { |e| [e, e] }]

With Array#to_h(Ruby >= 2.1):

使用Array#to_h(红宝石 >= 2.1):

hash = ['a', 'b'].map { |e| [e, e] }.to_h

With Enumerable#mashfrom Facets:

使用来自 Facets 的Enumerable#mash

require 'facets'
hash = ['a', 'b'].mash { |e| [e, e] }

回答by the Tin Man

Rather than using inject, you should look into Enumerable#each_with_object.

您应该查看Enumerable#each_with_object.

Where injectrequires you to return the object being accumulated into, each_with_objectdoes it automatically.

哪里inject需要你返回被累积的对象,each_with_object它会自动执行。

From the docs:

从文档:

Iterates the given block for each element with an arbitrary object given, and returns the initially given object.

If no block is given, returns an enumerator.

e.g.:

使用给定的任意对象迭代每个元素的给定块,并返回最初给定的对象。

如果没有给出块,则返回一个枚举器。

例如:

evens = (1..10).each_with_object([]) {|i, a| a << i*2 }
#=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

So, closer to your question:

所以,更接近你的问题:

[1] pry(main)> %w[a b].each_with_object({}) { |e,m| m[e] = e }
=> {"a"=>"a", "b"=>"b"}

Notice that injectand each_with_objectreverse the order of the yielded parameters.

请注意,injecteach_with_object反转产生参数的顺序。