如何在一行内遍历这个哈希值?
哈希中的每个键都有一个值,该值也是哈希。
{ 100 => { 1 => 'ruby', 2 => 'enumerables' }, 50 => { 3 => 'can', 4 => 'cause' }, 15 => { 5 => 'occassional', 6 => 'insanity' } }
对于每个哈希对象,我想丢弃顶级键,并将其替换为嵌套哈希对象的键和值。
{
1 => 'ruby',
2 => 'enumerables',
3 => 'can',
4 => 'cause',
5 => 'occasional',
6 => 'insanity'
}
我可以正常工作,但我的方法使用 merge!
,并且需要创建另一个哈希来存储值。我很好奇是否可以在一行中完成。我尝试使用reduce()
,但无法使其工作。
Each key in a hash has a value that's also a hash.
{ 100 => { 1 => 'ruby', 2 => 'enumerables' }, 50 => { 3 => 'can', 4 => 'cause' }, 15 => { 5 => 'occassional', 6 => 'insanity' } }
For each hash object, I want to discard the top-level key, and replace it with the key and value of the nested hash objects.
{
1 => 'ruby',
2 => 'enumerables',
3 => 'can',
4 => 'cause',
5 => 'occasional',
6 => 'insanity'
}
I have it working, but my method uses a merge!
, and requires creating another hash to store the values. I'm curious to see if it can be done in one line. I tried to use reduce()
, but could not make it work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这有效:
编辑:另一种选择,使用
reduce
(与inject
相同),并注意tokland的评论,即当你使用一个符号:那么它不仅变得简洁而且非常可读。
This works:
Edit: Another option, using
reduce
(which is the same asinject
), and noting tokland's comment that to_proc is automatically called when you use a symbol:Then it becomes not only concise but very readable.
我最喜欢 @MarkThomas 的答案,但为了速度和内存效率,我建议:
对当前答案进行 200,000 次迭代的基准测试表明这是最快的:
自从 @tokland 的评论 -
original.values.reduce(:update )
——修改原始哈希,我们无法将其直接与其他方法进行比较。但是,如果我们修改所有测试以将第一个哈希的重复项放回原始每次迭代中,@tokland 的答案将成为最快,尽管仍然不如我的那么快:如果您需要绝对速度并且可以修改原始值价值观,使用@tokland的答案。如果您这样做并希望完好无损地保留原始未合并的哈希值,那么您可以:
请注意,您的问题标题为遍历;如果您确实不想合并值(如果您可能想访问重复的键两次而不是最后一次获胜),那么只需执行以下操作:
I like the answer by @MarkThomas best, but for speed and memory efficiency I suggest:
Benchmarking 200,000 iterations of the current answers shows this to be the fastest:
Since the comment by @tokland—
original.values.reduce(:update)
—modifies the original hash we cannot compare it directly to the other methods. However, if we modify all tests to put a duplicate of the first hash back into the original each iteration, @tokland's answer becomes the fastest, though still not quite as fast as mine:If you need absolute speed and it's OK to modify the original values, use @tokland's answer. If you do so and want to preserve the original unmerged hashes unscathed, then you can:
Note that your question title says traverse; if you don't really want to merge the values—if you might want to visit a duplicate key twice instead of last-in-wins—then simply do:
由于您不重视顶级键,因此请使用 #values 获取值的数组(在本例中也是哈希值)。然后,您可以使用 #inject 构建新的哈希,并随时合并它们。
可能还有其他方法可以做到这一点。
Since you don't value about the top level keys, use #values to get an array of the values (in this case, also hashes). Then you can use #inject to build up a new hash, merging them as you go.
There are probably other ways to do it.
只是尝试了一下,第一次尝试是蛮力,更好的方法(在这个词的两种意义上......)就在那里。
Just took a stab at it, first try was brute force and better methods (in both senses of the word...) are out there.
虽然它不像其他一些答案那么简短,但我认为
each_with_object
值得一个表示。While it isn't as brief as some of the other answers, I think
each_with_object
deserves a representation.