PHP尽管有缺点,但在这方面做得很好。数组和哈希之间没有区别(也许我很天真,但这对我来说显然是正确的),要遍历其中任何一个,你都可以这样做

foreach (array/hash as $key => $value)

在Ruby中,有很多方法可以做到这一点:

array.length.times do |i|
end

array.each

array.each_index

for i in array

哈希更有意义,因为我总是用

hash.each do |key, value|

为什么我不能对数组这样做?如果我只想记住一个方法,我想我可以使用each_index(因为它使索引和值都可用),但是必须使用array[index]而不是value是很烦人的。


哦,对了,我忘了array。each_with_index。然而,这个很糟糕,因为它是|值,键|和哈希。每个键|,值|!这不是很疯狂吗?


当前回答

试图对数组和哈希始终如一地做同样的事情可能只是代码的味道,但是,冒着被打上令人讨厌的半猴子补丁的风险,如果您正在寻找一致的行为,这能做到吗?:

class Hash
    def each_pairwise
        self.each { | x, y |
            yield [x, y]
        }
    end
end

class Array
    def each_pairwise
        self.each_with_index { | x, y |
            yield [y, x]
        }
    end
end

["a","b","c"].each_pairwise { |x,y|
    puts "#{x} => #{y}"
}

{"a" => "Aardvark","b" => "Bogle","c" => "Catastrophe"}.each_pairwise { |x,y|
    puts "#{x} => #{y}"
}

其他回答

以下是你问题中列出的四个选项,按控制自由程度排列。您可能想要使用不同的方法,这取决于您需要什么。

简单回顾一下价值观: array.each 简单地看一下索引: array.each_index 遍历索引+索引变量: 对于数组中的I 控制循环计数+索引变量: array。length。乘以do | I |

试图对数组和哈希始终如一地做同样的事情可能只是代码的味道,但是,冒着被打上令人讨厌的半猴子补丁的风险,如果您正在寻找一致的行为,这能做到吗?:

class Hash
    def each_pairwise
        self.each { | x, y |
            yield [x, y]
        }
    end
end

class Array
    def each_pairwise
        self.each_with_index { | x, y |
            yield [y, x]
        }
    end
end

["a","b","c"].each_pairwise { |x,y|
    puts "#{x} => #{y}"
}

{"a" => "Aardvark","b" => "Bogle","c" => "Catastrophe"}.each_pairwise { |x,y|
    puts "#{x} => #{y}"
}

我一直在尝试使用散列构建菜单(在Camping和Markaby中)。

每个项目都有两个元素:一个菜单标签和一个URL,所以哈希似乎是正确的,但“Home”的“/”URL总是出现在最后(正如你所期望的哈希),所以菜单项出现的顺序是错误的。

使用带有each_slice的数组来完成这项工作:

['Home', '/', 'Page two', 'two', 'Test', 'test'].each_slice(2) do|label,link|
   li {a label, :href => link}
end

为每个菜单项添加额外的值(例如CSS ID名)只是意味着增加切片值。就像一个散列,但是组由任意数量的项组成。完美的。

所以这只是为了感谢你无意中暗示了一个解决方案!

很明显,但值得说明:我建议检查数组的长度是否能被切片值整除。

使用相同的方法迭代数组和散列是有意义的,例如处理嵌套的散列和数组结构,通常由解析器产生,读取JSON文件等。

一个尚未被提及的聪明方法是如何在标准库扩展的Ruby Facets库中实现它。从这里开始:

class Array

  # Iterate over index and value. The intention of this
  # method is to provide polymorphism with Hash.
  #
  def each_pair #:yield:
    each_with_index {|e, i| yield(i,e) }
  end

end

已经有哈希#each_pair,哈希#each的别名。所以在这个补丁之后,我们也有了数组#each_pair,并且可以互换地使用它来遍历哈希和数组。这修复了OP观察到的array# each_with_index与Hash#each相比块参数颠倒的疯狂。使用示例:

my_array = ['Hello', 'World', '!']
my_array.each_pair { |key, value| pp "#{key}, #{value}" }

# result: 
"0, Hello"
"1, World"
"2, !"

my_hash = { '0' => 'Hello', '1' => 'World', '2' => '!' }
my_hash.each_pair { |key, value| pp "#{key}, #{value}" }

# result: 
"0, Hello"
"1, World"
"2, !"

在Ruby 2.1中,each_with_index方法被移除。 相反,您可以使用each_index

例子:

a = [ "a", "b", "c" ]
a.each_index {|x| print x, " -- " }

生产:

0 -- 1 -- 2 --