2012-05-25 12 views
6

El código corto en el título es en Haskell, que hace cosas comoimplementar Elegantemente 'mapa (1) Lista' en rubí

list.map {|x| x + 1} 

en rubí.

Si bien sé de esa manera, pero lo que quiero saber es si hay más modales elegantes para implementar lo mismo en Ruby como en Haskell.

Me encanta el acceso directo to_proc de rubí, de esta forma:

[1,2,3,4].map(&:to_s) 
[1,2,3,4].inject(&:+) 

Pero este número argumento sólo aceptar que coincide exactamente entre el Proc y el método de.

Estoy tratando de buscar una manera que permita pasar uno o más argumentos extra en el Proc, y sin usar un bloque/variable temporal inútil como lo hace la primera demostración.

que quiero hacer la siguiente manera:

[1,2,3,4].map(&:+(1)) 

¿Se han rubí maneras similares para hacer esto?

+0

Vi una joya el otro día, pero no recuerdo cómo se llamaba excepto 'X'. –

+0

@JoshLee Si puede recordar la gema, sería muy apreciada. –

+0

Aha, lo vimos en Hacker News. http://news.ycombinator.com/item?id=4003805 –

Respuesta

5

Uso del ampex gema, que le permite utilizar métodos de X para desarrollar cualquier proc uno una variable . He aquí un ejemplo de su especificación:

["a", "b", "c"].map(&X * 2).should == ["aa", "bb", "cc"] 
+0

¡Joya genial! ¡Creo que eso es exactamente lo que quiero! –

0

Si lo que desea es añadir al menos 1, puede utilizar next o succ:

[1,2,3,4].map(&:next) 
[1,2,3,4].map(&:succ) 
7

Si lo que desea es añadir una a continuación, puede utilizar la succ method:

>> [1,2,3,4].map(&:succ) 
=> [2, 3, 4, 5] 

Si quería para agregar dos, puede usar una lambda:

>> add_2 = ->(i) { i + 2 } 
>> [1,2,3,4].map(&add_2) 
=> [3, 4, 5, 6] 

Para arbitrario valores, se podría utilizar un lambda que construye lambdas:

>> add_n = ->(n) { ->(i) { i + n } } 
>> [1,2,3,4].map(&add_n[3]) 
=> [4, 5, 6, 7] 

También podría utilizar un método de generación de lambda:

>> def add_n(n) ->(i) { i + n } end 
>> [1,2,3,4].map(&add_n(3)) 
=> [4, 5, 6, 7] 
+0

No agregar uno solo. Parece que tengo que cambiar los códigos de ejemplo para evitar malentendidos ;-) –

+0

@ShouYa: Pero es por eso que también hay todas las cosas de 'add_n'. –

3

Usted no puede hacerlo directamente con el valor por defecto map. Sin embargo, es bastante fácil implementar una versión que admita este tipo de funcionalidad. A modo de ejemplo Ruby Facets incluye sólo un procedimiento de este tipo:

require 'facets/enumerable' 

[1, 2, 3, 4].map_send(:+, 10) 
=> [11, 12, 13, 14] 

La puesta en práctica se parece a esto:

def map_send(meth, *args, &block) 
    map { |e| e.send(meth, *args, &block) } 
end 
1

Ruby no ha incorporado en el soporte para esta función, pero puede crear su propia extensión o utilizar pequeña joya 'ampex'. Define la variable global X con la funcionalidad extendida 'to_proc'.

que le da la posibilidad de hacer eso:

[1,2,3].map(&X.+(1)) 

O incluso que:

"alpha\nbeta\ngamma\n".lines.map(&X.strip.upcase) 
2

En este particular caso, puede utilizar el siguiente:

[1, 2, 3, 4].map(&1.method(:+)) 

Sin embargo, esto solo funciona porque + no está asociado ve. No funcionaría para -, por ejemplo.

Cuestiones relacionadas