2011-05-12 10 views
40

Si tengo arr = [1, 2, 3, 4] sé que puedo hacer lo siguiente ...matriz de Ruby each_slice_with_index?

> arr.each_slice(2) { |a, b| puts "#{a}, #{b}" } 
1, 2 
3, 4 

... Y ...

> arr.each_with_index { |x, i| puts "#{i} - #{x}" } 
0 - 1 
1 - 2 
2 - 3 
3 - 4 

... Pero es que hay una construida en la forma de hacer esto ?

> arr.each_slice_with_index(2) { |i, a, b| puts "#{i} - #{a}, #{b}" } 
0 - 1, 2 
2 - 3, 4 

Sé que puedo construir mi propio y pegarlo en el método de matriz. Solo estoy mirando para ver si hay una función incorporada para hacer esto.

Respuesta

79

Al igual que la mayoría de los métodos de iterador, each_slice devuelve un enumerable cuando se llama sin un bloque desde ruby ​​1.8.7+, que luego puede llamar a otros métodos enumerables. Entonces usted puede hacer:

arr.each_slice(2).with_index { |(a, b), i| puts "#{i} - #{a}, #{b}" } 
+3

muy fresco! Solo para completar mi problema original, necesitaría hacer # {i * 2} para obtener el índice en el arr original y no el índice en el enumerable en rodajas. – Drew

6

En 1.9 muchos métodos devuelven un enumerador si no se proporciona ningún bloque. Puede llamar a otro método en el enumerador.

arr = [1, 2, 3, 4, 5, 6, 7, 8] 
arr.each_with_index.each_slice(2){|(a,i), (b,j)| puts "#{i} - #{a}, #{b}"} 

(Variation on @ sepp2k). Resultado:

0 - 1, 2 
2 - 3, 4 
4 - 5, 6 
6 - 7, 8 
10
arr.each_slice(2).with_index { |(*a), i| ... 

también en cuenta que la matriz, primer parámetro del bloque, puede ser * arr