rails link_to content_tag ruby-on-rails ruby

ruby-on-rails - content_tag link_to rails



¿Cómo seleccionas cada elemento nth en una matriz? (8)

Estoy buscando una manera de seleccionar Ruby en cada elemento en una matriz. Por ejemplo, seleccionar cada segundo elemento transformaría:

["cat", "dog", "mouse", "tiger"]

dentro:

["dog", "tiger"]

¿Hay un método de Ruby para hacerlo, o hay alguna otra manera de hacerlo?

Intenté usar algo como:

[1,2,3,4].select {|x| x % 2 == 0} # results in [2,4]

pero eso solo funciona para una matriz con enteros, no cadenas.


Me gustan tanto las respuestas de Anshul como las de Mu y quiero refinarlas y simplificarlas un poco enviándolas como un Monkeypatch a Enumerable:

De mu

module Enumerable def every_nth(n) (n - 1).step(self.size - 1, n).map { |i| self[i] } end end

De Anshul

module Enumerable def every_nth(n) (0... self.length).select{ |x| x%n == n-1 }.map { |y| self[y] } end end

Entonces es muy fácil trabajar con él. Por ejemplo, considere:

a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25] a.every_nth(2) => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24] a.every_nth(3) => [3, 6, 9, 12, 15, 18, 21, 24] a.every_nth(5) => [5, 10, 15, 20, 25]


Otra forma más:

xs.each_with_index.map { |x, idx| x if idx % 2 != 0 }.compact xs.each_with_index.select { |x, idx| idx % 2 }.map(&:first) xs.values_at(*(1...xs.length).step(2))


Puedes usar Enumerable#each_slice :

["cat", "dog", "mouse", "tiger"].each_slice(2).map(&:last) # => ["dog", "tiger"]

Actualizar:

Como se mencionó en el comentario, el last no siempre es adecuado, por lo que podría ser reemplazado por el primer elemento y omitir el primer elemento:

["cat", "dog", "mouse", "tiger"].drop(1).each_slice(2).map(&:first)

Desafortunadamente, haciéndolo menos elegante.

En mi opinión, lo más elegante es usar .select.with_index , que Nakilon sugirió en su comentario:

["cat", "dog", "mouse", "tiger"].select.with_index{|_,i| (i+1) % 2 == 0}


Qué tal esto -

arr = ["cat", "dog", "mouse", "tiger"] n = 2 (0... arr.length).select{ |x| x%n == n-1 }.map { |y| arr[y] } #=> ["dog", "tiger"]


Si necesita eso en otros lugares, puede agregar un método a Enumerable :

module Enumerable def select_with_index index = -1 (block_given? && self.class == Range || self.class == Array) ? select { |x| index += 1; yield(x, index) } : self end end p ["cat", "dog", "mouse", "tiger"].select_with_index { |x, i| x if i % 2 != 0 }

Nota: Este no es mi código original. Lo obtuve de here cuando tuve la misma necesidad que tú.


Simplemente puedes usar el método values_at . Puedes encontrarlo fácilmente en la documentation .

Aquí hay unos ejemplos:

array = ["Hello", 2, "apple", 3] array.values_at(0,1) # pass any number of arguments you like => ["Hello", 2] array.values_at(0..3) # an argument can be a range =>["Hello", 2, "apple", 3]

Creo que esto solucionaría tu problema con "perro" y "tigre"

array = ["cat", "dog", "mouse", "tiger"] array.values_at(1,3)

y con tu otra matriz

[1,2,3,4].values_at(1,3) => [2, 4]


Sugeriría una manera muy simple:

animals.select.with_index{ |_, i| i.odd? }

p.ej

[''a'',''b'',''c'',''d''].select.with_index{ |_,i| i.odd? } # => ["b", "d"]


También puedes usar el paso:

n = 2 a = ["cat", "dog", "mouse", "tiger"] b = (n - 1).step(a.size - 1, n).map { |i| a[i] }