Ruby注入初始为哈希

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ruby注入初始为哈希相关的知识,希望对你有一定的参考价值。

可以任何人告诉我为什么以下:

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

抛出错误:

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

而以下工作?

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

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

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

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

另一答案

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

使用Hash#update

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

使用Enumerable#each_with_object

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

使用Hash#[]

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

使用Array#to_h(Ruby> = 2.1):

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

来自Facets的Enumerable#mash

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

而不是使用注入,你应该看看Enumerable#each_with_object

如果inject要求您返回正在累积的对象,each_with_object会自动执行此操作。

来自文档:

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

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

e.f.:

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

所以,更接近你的问题:

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

请注意,injecteach_with_object颠倒了所产生参数的顺序。

以上是关于Ruby注入初始为哈希的主要内容,如果未能解决你的问题,请参考以下文章

ruby 如何从超类初始化关键字参数(对依赖注入很有用)

将 Nokogiri 文档转换为 Ruby 哈希

ruby 哈希包含另一个哈希,深度检查

如何表示将 ruby​​ 哈希转换为 yaml 的 aws 内部函数

如何将 JSON 转换为 Ruby 哈希

Ruby 将对象转换为哈希