Ruby:将数组转换为哈希时注入问题 [英] Ruby: inject issue when turning array into hash
问题描述
当我运行这个时,我得到一个索引错误
当我将块更改为
<前>a.inject({}) {|r, val|r[val[0]] = val[1];r}然后就可以了.
ruby 如何处理第一次没有得到我想要的注入尝试?
有没有更好的方法来做到这一点?
仅仅因为 Ruby 是动态和隐式类型并不意味着您不必考虑类型.
没有显式累加器的 Enumerable#inject
类型(通常称为 reduce
)类似于
reduce :: [a] → (a → a → a) → a
或者用我刚刚编写的更像红宝石的符号
Enumerable[A]#inject {|A, A|A } → A
您会注意到所有类型都是相同的.Enumerable
的元素类型,块的两个参数类型,块的返回类型和整体方法的返回类型.
Enumerable#inject
带有显式累加器(通常称为fold
)的类型类似于
fold :: [b] → a → (a → b → a) → a
或
Enumerable[B]#inject(A) {|A, B|A } → A
在这里您看到累加器可以具有与集合的元素类型不同的类型.
这两条规则通常可以帮助您解决所有与 Enumerable#inject
相关的类型问题:
- 累加器的类型和块的返回类型必须相同
- 不传递显式累加器时,累加器的类型与元素类型相同
在这种情况下,第 1 条规则会咬你.当你做类似的事情
acc[key] = 值
在您的块中,分配评估为分配的值,而不是分配的接收者.您必须将其替换为
acc.tap { acc[key] = value }
<小时>顺便说一句:您可以使用解构绑定使您的代码更具可读性:
a.inject({}) {|r, (key, value)|r[key] = 值;r }
a = [[1, 'a'],[2, 'b'],[3, 'c'], [4, 'd']] a.inject({}) {|r, val| r[val[0]] = val[1]}
When I run this, I get an index error
When I change the block to
a.inject({}) {|r, val| r[val[0]] = val[1]; r}
It then works.
How is ruby handling the first inject attempt that isn't getting what I want?
Is there a better way to do this?
Just because Ruby is dynamically and implicitly typed doesn't mean that you don't have to think about types.
The type of Enumerable#inject
without an explicit accumulator (this is usually called reduce
) is something like
reduce :: [a] → (a → a → a) → a
or in a more Rubyish notation I just made up
Enumerable[A]#inject {|A, A| A } → A
You will notice that all the types are the same. The element type of the Enumerable
, the two argument types of the block, the return type of the block and the return type of the overall method.
The type of Enumerable#inject
with an explicit accumulator (this is usually called fold
) is something like
fold :: [b] → a → (a → b → a) → a
or
Enumerable[B]#inject(A) {|A, B| A } → A
Here you see that the accumulator can have a different type than the element type of the collection.
These two rules generally get you through all Enumerable#inject
-related type problems:
- the type of the accumulator and the return type of the block must be the same
- when not passing an explicit accumulator, the type of the accumulator is the same as the element type
In this case, it is Rule #1 that bites you. When you do something like
acc[key] = value
in your block, assignments evaluate to the assigned value, not the receiver of the assignment. You'll have to replace this with
acc.tap { acc[key] = value }
See also Why Ruby inject method cannot sum up string lengths without initial value?
BTW: you can use destructuring bind to make your code much more readable:
a.inject({}) {|r, (key, value)| r[key] = value; r }
这篇关于Ruby:将数组转换为哈希时注入问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!