Consejos para jugar golf en Ruby


62

¿Qué consejos generales puedes dar para jugar al golf en Ruby?

Estoy buscando ideas que se puedan aplicar a los problemas de código de golf en general que sean específicos de Ruby. (Por ejemplo, "Eliminar comentarios" no sería una respuesta).

Por favor, publique un consejo por respuesta.


Alguien necesita escribir un lenguaje llamado Rub, que usa un solo carácter Unicode para cada ficha Ruby, algo así como Jelly y Pyth :)
Mark Thomas

Respuestas:


46
  • El 100 números a 126 se puede escribir como ?da ?~en 1.8.
  • En una nota similar, si necesita una cadena de un solo carácter en 1.9? X es más corta que "x".
  • Si necesita imprimir una cadena sin agregar una nueva línea, $><<"string"es más corta que print"string".
  • Si necesita leer varias líneas de entrada $<.map{|l|...}es más corto que while l=gets;...;end. También puedes usarlo $<.readpara leerlo todo de una vez.
  • Si se supone que debe leer desde un archivo, $<y getsleerá desde un archivo en lugar de stdin si el nombre de archivo está en ARGV. Así que la forma golfiest volver a implementar catsería: $><<$<.read.

1
? x produce el código ASCII en general, por lo que puede obtener de manera realista todos los imprimibles en dígitos en dos caracteres. 1.9 es diferente, 'a'.ord produce el número ascii, pero es cuatro bytes más largo que la versión decimal.
Hiato

8
Una forma aún más innovadora de implementar cates dejar el archivo ruby ​​completamente vacío (0 bytes) e insistir en que se ejecute desde la línea de comando con la -pbandera.
daniero

1
o, de la propia respuesta de @ daniero ,puts *$<
No es que Charles

1
Entonces, en 1.8, ¿todo lo que tengo que hacer es ir? ~ Y me devolverá 126?
Simply Beautiful Art

55
Puedes ir más allá de 126 usando pensar como o , o si estás lo suficientemente loco:?﷽.ord=65021
Simply Beautiful Art

32

Use el operador splat para obtener la cola y la cabeza de una matriz:

head, *tail = [1,2,3]
head => 1
tail => [2,3]

Esto también funciona a la inversa:

*head, tail = [1,2,3]
head => [1,2]
tail => 3

Use el *método con una cadena en una matriz para unir elementos:

[1,2,3]*?,
=> "1,2,3"

27
  • Use abortpara terminar el programa e imprimir una cadena en STDERR, más corta que la putsseguida porexit
  • Si lee una línea con gets, puede usarla ~/$/para encontrar su longitud (esto no cuenta una nueva línea final si existe)
  • Use []para verificar si una cadena contiene otra:'foo'['f'] #=> 'f'
  • Use en trlugar de gsubsustituciones de carácter sabio:'01011'.tr('01','AB') #=> 'ABABB'
  • Si necesita eliminar las nuevas líneas finales, use en choplugar dechomp

2
+1 para aborty~/$/
J -_- L

Por favor explique cómo usar~/$/
Mathieu CAROFF

@MathieuCAROFF cada vez que llama gets, su resultado se almacena en la $_variable. /regex/ ~= stringDevuelve el índice del primer partido. Llamar ~a una expresión regular es equivalente a /regex/ ~= $_. Entonces sería algo asís=gets;l= ~/$/
Cyoce

20

Termina tu end.

Intenta eliminarlo endde tu código.

No lo use def...endpara definir funciones. Haga una lambda con el nuevo operador -> en Ruby 1.9. (El operador -> es un "stada lambda", o "cohete guión" ). Esto ahorra 5 caracteres por función.

# 28 characters
def c n
/(\d)\1/=~n.to_s
end

# 23 characters, saves 5
c=->n{/(\d)\1/=~n.to_s}

Las llamadas al método son c no c(n). Las llamadas de Lambda son c[n]. Cambiando cada c na c[n]los costos de 1 carácter, por lo que si se puede usar c nmás de 5 veces, a continuación, seguir el método.

Todos los métodos que toman do...endbloques pueden tomar {...}bloques en su lugar. Esto ahorra de 3 a 5 caracteres. Si la precedencia de {...}es demasiado alta, utilice paréntesis para solucionarlo.

# 48 characters
(?a..?m).zip (1..5).cycle do|a|puts a.join','end

# WRONG: passes block to cycle, not zip
(?a..?m).zip (1..5).cycle{|a|puts a.join','}

# 45 characters, saves 3
(?a..?m).zip((1..5).cycle){|a|puts a.join','}

Reemplace if...else...endcon el operador ternario ?: . Si una rama tiene dos o más declaraciones, envuélvalas entre paréntesis.

# 67 characters
if a<b
puts'statement 1'
puts'statement 2'else
puts'statement 3'end

# 62 characters, saves 5
a<b ?(puts'statement 1'
puts'statement 2'):(puts'statement 3')

Probablemente no tenga whileni untilbucles, pero si los tiene, escríbalos en forma de modificador.

(a+=1
b-=1)while a<b

¿Son puts'statement 3'necesarios los paréntesis ?
Cyoce

15

Adición a w0lf

Cuando se trabaja con matrices, .compactse puede reemplazar con -[nil]para guardar 2 caracteres.

Combinado con el anterior -> puede hacerlo aún más corto -[p]para guardar otros 2 caracteres.


14

Utilice las variables predefinidas cortas siempre que sea posible, por ejemplo, en $*lugar de ARGV. Hay una buena lista de ellos aquí , junto con una gran cantidad de otra información útil.


12

Cuando utiliza la interpolación de cadenas (como debería hacer con la publicación de Martin Büttner ), no necesita los corchetes si su objeto tiene un sigilo ( $, @) delante. Útil para las variables mágicos como $_, $&, $1etc:

puts "this program has read #$. lines of input"

Por lo tanto, si necesita imprimir una variable más de lo que usa, de lo contrario, puede guardar algunos bytes.

a=42; puts "here is a: #{a}"; puts "here is a again: #{a}"
$b=43; puts "here is b: #$b"; puts "here is b again: #$b"

11

Si necesita encontrar si un elemento en particular eestá dentro de un rango r, puede usar

r===e

en lugar del más largo:

r.cover?(e) # only works if `r.exclude_end?` is false

o

r.member?(e)

o

r.include?(e)

3
¿Ni r===esiquiera es más corto?
akuhn

@akuhn Sí, lo es. Mucho más corto. Gracias por señalarlo, me ayudó a acortar mi código en 10 caracteres, que es enorme: codegolf.stackexchange.com/a/6125/3527
Cristian Lupascu

1
De nada. Se ha ===implementado todo lo que se puede usar en una declaración de cambio .
akuhn

10

$_ es la última línea leída.

  • print - si no hay argumento dado el contenido impreso de $_
  • ~/regexp/ - corto para $_=~/regexp/

En Ruby 1.8, tiene cuatro métodos Kernelque operan en $_:

  • chop
  • chomp
  • sub
  • gsub

En Ruby 1.9, estos cuatro métodos existen solo si su script usa -no -p.

Si desea imprimir alguna variable con frecuencia, use trace_var(:var_name){|a|p a}


2
Estos solo están disponibles cuando ejecuta Ruby con la opción -po -n. Referencia.
Darren Stone

1
Parece que trace_varsolo funciona con variables globales $
daniero

10

¡Usa la interpolación de cuerdas!

  1. Para reemplazar to_s. Si necesita paréntesis alrededor de lo que quiera convertir en una cadena, to_ses dos bytes más largo que la interpolación de cadenas:

    (n+10**i).to_s
    "#{n+10**i}"
    
  2. Para reemplazar la concatenación. Si concatena algo rodeado por otras dos cadenas, la interpolación puede ahorrarle un byte:

    "foo"+c+"bar"
    "foo#{c}bar"
    

    También funciona si la cosa del medio está concatenada, si solo mueve la concatenación dentro de la interpolación (en lugar de usar interpolaciones múltiples):

    "foo"+c+d+e+"bar"
    "foo#{c+d+e}bar"
    

10

Evitar lengthenif a.length<n

lengthes de 6 bytes, un poco costoso en el código de golf. en muchas situaciones, puede verificar si la matriz tiene algo en un punto dado. si pasas el último índice que obtendrás nil, un valor falsey.

Para que pueda cambiar:

if a.length<5a if !a[4]de -5 bytes

o

if a.length>5a if a[5]de -6 bytes

o

if a.length<na if !a[n-1]para -3 bytes

o

if a.length>na if a[n]de -6 bytes

Nota : solo funcionará con una matriz de todos los valores de verdad. tener nilo falsedentro de la matriz puede causar problemas.


44
Siempre uso size... Pero esto definitivamente es mejor. Por cierto, también funciona para String.
manatwork

10

No use las palabras clave truey false.

Utilizar:

  • !ppor true(gracias, histocrat!)
  • !0para false. Si todo lo que necesita es un valor falso, simplemente puede usar p(que devuelve nil).

para guardar algunos caracteres


1
A menos que realmente lo necesite true(es decir, si un valor verdadero es suficiente, como en una condición if), ni siquiera lo necesita !!.
Martin Ender

44
Y de manera similar, p(que se evalúa como nil) es un valor de falsey más corto. Lo que significa que la forma más corta de llegar truees !p.
histocrat

@histocrat buen punto! He editado mi respuesta.
Cristian Lupascu


9

Si alguna vez necesita obtener un número de ARGV, geto algo similar para hacer algo que muchas veces, en lugar de invocarlo to_i, puede usar ?1.upto x{do something x times}donde x es una cadena.

Por lo tanto, usar en ?1.upto(a){}lugar de x.to_i.times{}le ahorrará 2 caracteres.

También puedes volver a escribir cosas como p 1 while 1o p 1 if 1como p 1while 1op 1if 1

Ese ejemplo no es muy útil, pero podría usarse para otras cosas.

Además, si necesita asignar el primer elemento de una matriz a una variable, a,=cguardará dos caracteres en lugar dea=c[0]


9

Nuevas características en Ruby 2.3 y 2.4

Es bueno estar al tanto de las nuevas características del lenguaje que ayudarán a su juego de golf. Hay algunos geniales en los últimos Rubies.

Ruby 2.3

El operador de navegación segura: &.

Cuando llama a un método que puede regresar nilpero desea encadenar llamadas de método adicionales si no es así, desperdicia bytes manejando el nilcaso:

arr = ["zero", "one", "two"]
x = arr[5].size
# => NoMethodError: undefined method `size' for nil:NilClass

x = arr[5].size rescue 0
# => 0

El "operador de navegación segura" detiene la cadena de llamadas a métodos si uno regresa nily regresa nilpara la expresión completa:

x = arr[5]&.size || 0
# => 0

Array#dig Y Hash#dig

Acceso profundo a elementos anidados, con un bonito nombre corto:

o = { foo: [{ bar: ["baz", "qux"] }] }
o.dig(:foo, 0, :bar, 1) # => "qux"

Devuelve nilsi llega a un callejón sin salida:

o.dig(:foo, 99, :bar, 1) # => nil

Enumerable#grep_v

El inverso de: Enumerable#grepdevuelve todos los elementos que no coinciden con el argumento dado (en comparación con ===). Por ejemplo grep, si se da un bloque, se devuelve su resultado.

(1..10).grep_v 2..5 # => [1, 6, 7, 8, 9, 10]
(1..10).grep_v(2..5){|v|v*2} # => [2, 12, 14, 16, 18, 20]

Hash#to_proc

Devuelve un Proc que produce el valor de la clave dada, que puede ser bastante útil:

h = { N: 0, E: 1, S: 2, W: 3 }
%i[N N E S E S W].map(&h)
# => [0, 0, 1, 2, 1, 2, 3]

Ruby 2.4

Ruby 2.4 aún no está disponible, pero lo estará pronto y tiene algunas características excelentes. (Cuando se publique, actualizaré esta publicación con algunos enlaces a los documentos). Aprendí sobre la mayoría de estos en esta gran publicación de blog .

Enumerable#sum

No más arr.reduce(:+). Ahora solo puedes hacer arr.sum. Toma un argumento opcional de valor inicial, que por defecto es 0 para elementos numéricos ( [].sum == 0). Para otros tipos, deberá proporcionar un valor inicial. También acepta un bloque que se aplicará a cada elemento antes de la adición:

[[1, 10], [2, 20], [3, 30]].sum {|a,b| a + b }
# => 66

Integer#digits

Esto devuelve una matriz de dígitos de un número en orden de importancia menor a mayor:

123.digits # => [3, 2, 1]

Comparado con, digamos 123.to_s.chars.map(&:to_i).reverse, esto es bastante bueno.

Como beneficio adicional, se necesita un argumento de raíz opcional:

a = 0x7b.digits(16) # => [11, 7]
a.map{|d|"%x"%d} # => ["b", "7"]

Comparable#clamp

Hace lo que dice en la lata:

v = 15
v.clamp(10, 20) # => 15
v.clamp(0, 10) # => 10
v.clamp(20, 30) # => 20

Como está en Comparable, puede usarlo con cualquier clase que incluya Comparable, por ejemplo:

?~.clamp(?A, ?Z) # => "Z"

String#unpack1

Un ahorro de 2 bytes sobre .unpack(...)[0]:

"👻💩".unpack(?U)    # => [128123]
"👻💩".unpack(?U)[0] # => 128123
"👻💩".unpack1(?U)   # => 128123

Argumento de precisión para Numeric#ceil, floorytruncate

Math::E.ceil(1) # => 2.8
Math::E.floor(1) # => 2.7
(-Math::E).truncate(1) # => -2.7

Asignación múltiple en condicionales

Esto genera un error en versiones anteriores de Ruby, pero está permitido en 2.4.

(a,b=1,2) ? "yes" : "no" # => "yes"
(a,b=nil) ? "yes" : "no" # => "no"

Golf Math::E.ceil(1)a Math::E.ceil 1, y también para floory truncate.
Simplemente hermoso arte

1
@SimplyBeautifulArt Espero que alguien jugando al golf en Ruby pueda dar ese salto por sí mismo.
Jordan

Para Enumerable#sum, .flatten.sumes 2 bytes más corto que.sum{|a,b|a+b}
Asone Tuhid

(-Math::E).truncate(1)es equivalente a -Math::E.truncate(1)que es 1 byte más corto
Asone Tuhid

1
&.se puede usar con subíndice como este a&.[]i(1 byte más corto que a&.at i). Aunque, si se requieren paréntesis, a||a[i]es 1 byte más corto que a&.[](i)oa&.at(i)
Asone Tuhid

7

La notación científica a menudo se puede usar para afeitarse un char o dos:

x=1000
#versus
x=1e3

99
Nota: Esto devolverá un valor flotante (1000.0) en lugar de un entero, lo que puede causar resultados inexactos con números grandes.
Dogbert

44
Ah, 1e2mejor es mejor que 100.0cuando se necesita un porcentaje.
Phrogz

Similar a este principio, 1.0*es 1 char más corto que.to_f
Unihedron

7

Use métodos de operador en lugar de paréntesis

Digamos que quieres expresar a*(b+c). Debido a la precedencia, a*b+cno funcionará (obviamente). ¡La forma genial de Ruby de tener operadores como métodos viene al rescate! Puede usar a.*b+cpara hacer que la precedencia sea *menor que la de +.

a*(b+c) # too long
a*b+c   # wrong
a.*b+c  # 1 byte saved!

Esto también puede funcionar con los operadores !y ~(cosas como unary +o unary -no funcionan porque sus métodos son -@y +@, guardando ()pero agregando .@)

(~x).to_s # too long
~x.to_s   # error
x.~.to_s  # 1 byte saved!

6

Use en su ||lugar ory &&en su lugar and.

Al lado del único personaje de andusted puede guardar los espacios (y quizás el corchete) alrededor del operador.

p true and false ? 'yes' :'no'   #-> true (wrong result)
p (true and false) ? 'yes' :'no' #-> 'no'
p true&&false ? 'yes' :'no'      #-> 'no', saved 5 characters


p true or false ? 'yes' :'no'   #-> true (wrong result)
p (true or false) ? 'yes' :'no' #-> 'yes'
p true||false ? 'yes' :'no'      #-> 'yes', saved 4 characters

Si realiza un bucle en una matriz que normalmente usa each. Pero maptambién recorre una matriz y es un carácter más corto.


6

Acabo de intentar un desafío de código de golf TDD, es decir, escribir el código más corto para hacer pasar las especificaciones. Las especificaciones eran algo así como

describe PigLatin do
  describe '.translate' do
    it 'translates "cat" to "atcay"' do
      expect(PigLatin.translate('cat')).to eq('atcay')
    end
    # And similar examples for .translate
  end
end

Por el bien del código-golf, uno no necesita crear un módulo o clase.

En lugar de

module PigLatin def self.translate s;'some code'end;end

uno puede hacer

def(PigLatin=p).translate s;'some code'end

¡Salva a 13 personajes!


77
Ja, muy minucioso. No solamente se agrega el comportamiento necesario PigLatin, sino también para @pig_latin, $pig_latiny 'pig'['latin'].
histocrat

@histocrat: Ahora lo entiendo. Es porque translatese ha definido en nil.
Eric Duminil

6

Kernel # p es un método divertido.

Usar en p varlugar de puts var. Esto funciona perfectamente con enteros y flotantes, pero no con todos los tipos. Imprime comillas alrededor de las cadenas, lo que probablemente no sea lo que desea.

Utilizado con un solo argumento, pdevuelve el argumento después de imprimirlo.

Utilizado con múltiples argumentos, pdevuelve los argumentos en una matriz.

Use p(sin argumentos) en lugar de nil.


10
Lamentablemente p 'some string'imprime "some string"y no solo lo some stringque a menudo es criticado por otros.
Patrick Oscity

1
Básicamente p ses lo mismo puts s.inspect, pero regresas
Cyoce

6

No uses #each. Puede recorrer todos los elementos perfectamente con #map. Entonces en lugar de

ARGV.each{|x|puts x}

Puedes hacer lo mismo en menos bytes.

ARGV.map{|x|puts x}

Por supuesto, en este caso puts $*sería aún más corto.


Hay literales para números racionales y complejos:

puts 3/11r == Rational(3,11)
puts 3.3r == Rational(66,20)
puts 1-1.i == Complex(1,-1)

=> true
true
true

Puede usar la mayoría de los bytes dentro de las cadenas. "\x01"(6 bytes) se puede acortar a ""(3 bytes). Si solo necesita este byte, puede acortarlo aún más ?(2 bytes).

Del mismo modo, puede obtener nuevas líneas más cortas como esta:

(0..10).to_a.join'
'

 => "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"

Puede usar ?\ny ?\ttambién, que es un byte más corto que "\n"y "\t". Para la ofuscación, también hay? \ S, un espacio.


Use constantes en lugar de pasar argumentos, incluso si necesita cambiarlos. El intérprete dará advertencias a stderr , pero a quién le importa. Si necesita definir más variables relacionadas entre sí, puede encadenarlas así:

A=C+B=7+C=9

=> A=17, B=16, C=9

Esto es más corto que C=9;B=16;A=17o C=0;B=C+7;A=C+B.


Si necesita un bucle infinito, use loop{...}. Los bucles de longitud desconocida pueden ser más cortos con otros bucles:

loop{break if'
'==f(gets)}

while'
'!=f(gets);end

Algunos trucos más gsub / regexp. Use los '\1'caracteres de escape especiales en lugar de un bloque:

"golf=great short=awesome".gsub(/(\w+)=(\w+)/,'(\1~>\2)')

"golf=great short=awesome".gsub(/(\w+)=(\w+)/){"(#{$1}~>#{$2})")

Y las variables especiales, $1etc., si necesita realizar operaciones. Tenga en cuenta que se definen no solo dentro del bloque:

"A code-golf challenge." =~ /(\w+)-(\w+)/
p [$1,$2,$`,$']

=> ["code", "golf", "A ", " challenge."] 

Deshágase de espacios, líneas nuevas y paréntesis. Puedes omitir bastante en ruby. En caso de duda, intente siempre si funciona sin él, y tenga en cuenta que esto podría romper el resaltado de sintaxis del editor ...

x+=1if$*<<A==????::??==??

"Por favor, publique un consejo por respuesta". También ?\nes agradable, pero no es realmente más corto que poner un carácter de nueva línea entre comillas. (lo mismo para la pestaña)
Martin Ender

Y puts$*es aún más corto.
Cyoce

Yo sé que estabas tratando de demostrar un punto, pero estoy bastante seguro de que el último ejemplo es el mismo quex+=1;$*<<A
ASONE Tuhid

6

Otra forma más de utilizar el operador splat: si desea asignar un único literal de matriz, un *en el lado izquierdo es más corto que los corchetes en el lado derecho:

a=[0]
*a=0

Con múltiples valores, ni siquiera necesita el operador splat (gracias a histocrat por corregirme al respecto):

a=[1,2]
a=1,2

El último caso en realidad no necesita el splat.
histocrat

@histocrat Oh wow, pensé que el segundo valor sería descartado en ese caso.
Martin Ender

1
No puedo creer que no haya sabido esto en todo el tiempo que he pasado jugando al golf en Ruby.
Pomo de la puerta

6

Cuando un desafío requiere que varias líneas de salida, que no tienen que bucle a través de sus resultados con el fin de imprimir cada línea de, por ejemplo una matriz. El putsmétodo aplanará una matriz e imprimirá cada elemento en una línea separada.

> a = %w(testing one two three)
> puts a
testing
one
two
three

La combinación del operador splat con #pusted puede hacerlo aún más corto:

p *a

El operador splat (técnicamente el *@método, creo) también lanza sus enumerables que no son matrices a las matrices:

> p a.lazy.map{|x|x*2}
#<Enumerator::Lazy: #<Enumerator::Lazy: [1, 2, 3]>:map>

vs

> p *a.lazy.map{|x|x*2}
2
4
6

1
*@no es un método, splat es azúcar sintáctico
Asone Tuhid

6

Guarde algunos bytes al eliminar elementos repetidos de una matriz

a.uniq # before
a|[]   # after
    ^^

Si va a utilizar una matriz vacía []en una variable, puede guardar aún más bytes:

a.uniq;b=[] # before
a|b=[]      # after
      ^^^^^

2
Para el primer caso, a&aes 1 byte más corto
Asone Tuhid

5

Use Goruby en lugar de Ruby, que es algo así como una versión abreviada de Ruby. Puede instalarlo con rvm a través de

rvm install goruby

Goruby le permite escribir la mayor parte de su código como si estuviera escribiendo Ruby, pero tiene abreviaturas adicionales incorporadas. Para encontrar la abreviatura más corta disponible para algo, puede usar el método auxiliar shortest_abbreviation, por ejemplo:

shortest_abbreviation :puts
#=> "pts"

Array.new.shortest_abbreviation :map
#=> "m"

String.new.shortest_abbreviation :capitalize
#=> "cp"

Array.new.shortest_abbreviation :join
#=> "j"

También es muy útil el alias saypara el putscual se puede abreviar s. Entonces en lugar de

puts [*?a..?z].map(&:capitalize).join

ahora puedes escribir

s [*?a..?z].m(&:cp).j

imprimir el alfabeto en mayúsculas (que no es un muy buen ejemplo). Esta publicación de blog explica más cosas y algunos de los funcionamientos internos si está interesado en leer más.

PD: no te pierdas el hmétodo ;-)


Más de 2 años después y finalmente descubrí lo que me recuerda esta respuesta ...
undergroundmonorail

5

Para unir una matriz, en lugar de esto

[...].join

hacer esto

[...]*''

que ahorra 2 bytes. Para unirse con un separador use

[...]*?,

5

Números de suscripción!

Acabo de descubrir esto ayer. n[i]devuelve nel bit en la iposición -th. Ejemplo:

irb(main):001:0> n = 0b11010010
=> 210
irb(main):002:0> n[0]
=> 0
irb(main):003:0> n[1]
=> 1
irb(main):004:0> n[2]
=> 0
irb(main):005:0> n[3]
=> 0
irb(main):006:0> n[4]
=> 1
irb(main):007:0> n[5]
=> 0

Y ahora puedes usar más argumentos comon[0..3]
Simply Beautiful Art

4

Es posible que pueda guardar 2 caracteres y usar

[*(...)]

en lugar de

(...).to_a

Por ejemplo, supongamos que tenemos un rango que queremos como matriz:

(1..2000).to_a

Solo hazlo así:

[*1..2000]  #  Parentheses around the (ran..ge) is not needed!

Y ahora tienes tu rango como una matriz.


55
¿Creo que también [*1..2000]funciona?
Lynn

4

<< truco

a.push x

se puede acortar a:

a<<x

para -4 bytes.


2
Nota: esto también funciona para Strings
Cyoce

4

Array#assoc/ /rassoc

Cuando tenga una matriz de matrices y desee encontrar la sub-matriz que comienza con un valor particular, no use Enumerable#find, use Array#assoc:

a = [[0,"foo"],[0,"bar"],[1,"baz"],[0,"qux"]]
a.find{|x,|x==1} # => [1,"baz"]
a.assoc(1) # => [1,"baz"]

Este también es un buen reemplazo para Enumerable#any?en algunas situaciones.

Array#rassoc hace lo mismo, pero comprueba el último elemento de las submatrices:

a = [[123,"good"],[456,"good"]]
a.any?{|*,x|x=="bad"} # => false
a.rassoc("bad") # => nil

Para la a.any?línea del rassoc ejemplo, ¿qué hace |x,|? ¿Cómo es diferente de |x|?
Cyoce

@Cyoce bloque de parámetros desestructuración sigue las mismas reglas como asignación desestructurada, así que es como x=[1,2]vs x,=[1,2]. Usando mi ejemplo anterior, con |x|, en la primera iteración xserá [0,"foo"]. Con |x,y|, xserá 0y yserá "foo". Del mismo modo, con |x,|, xserá 0. En otras palabras, dice "pon el primer elemento xy tira el resto."
Jordania

Tenga en cuenta que no funciona a la inversa, por ejemplo, |,y|es un SyntaxError, ergo |_,y|. Pero ahora me he dado cuenta de que |*,y|funciona, que es más limpio que usar una variable llamada _(pero no más corta).
Jordania
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.