programmare - tutorial ruby




Qual è il modo "giusto" per scorrere attraverso un array in Ruby? (8)

Cercare di fare la stessa cosa in modo coerente con array e hash potrebbe essere solo un odore di codice, ma, a rischio di essere etichettato come un codificatore semi-scimmia, se stai cercando un comportamento coerente, questo dovrebbe essere il trucco ?:

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}"
}

PHP, per tutte le sue verruche, è abbastanza buono su questo conteggio. Non c'è differenza tra un array e un hash (forse sono ingenuo, ma questo sembra ovviamente giusto per me), e per scorrere avanti o fai semplicemente

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

In Ruby ci sono molti modi per fare questo genere di cose:

array.length.times do |i|
end

array.each

array.each_index

for i in array

Hash ha più senso, dal momento che lo uso sempre

hash.each do |key, value|

Perché non posso farlo per gli array? Se voglio ricordare solo un metodo, suppongo di poter usare each_index (poiché rende sia l'indice sia il valore disponibili), ma è fastidioso dover fare array[index] invece di solo value .

Oh, giusto, ho dimenticato array.each_with_index . Tuttavia, questo fa schifo perché va |value, key| e hash.each goes |key, value| ! Non è pazzesco?


Ecco le quattro opzioni elencate nella tua domanda, organizzate per libertà di controllo. Potresti volerne usare uno diverso a seconda di quello che ti serve.

  1. Basta passare attraverso i valori:

    array.each
  2. Basta consultare gli indici:

    array.each_index
  3. Passa attraverso indici + variabile indice:

    for i in array
  4. Conteggio loop di controllo + variabile indice:

    array.length.times do | i |

In Ruby 2.1, il metodo each_with_index viene rimosso. Invece puoi usare each_index

Esempio:

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

produce:

0 -- 1 -- 2 --

Le altre risposte vanno bene, ma volevo sottolineare un'altra cosa periferica: gli array sono ordinati, mentre gli Hash non sono in 1.8. (In Ruby 1.9, gli Hash sono ordinati per ordine di inserimento delle chiavi.) Quindi non avrebbe senso prima di 1.9 iterare su un hash nello stesso modo / sequenza degli array, che hanno sempre avuto un ordine preciso. Non so quale sia l'ordine predefinito per gli array associativi di PHP (a quanto pare il mio google fu non è abbastanza forte per capirlo), ma non so come si possano considerare i normali array PHP e gli array associativi di PHP per essere "lo stesso" in questo contesto, poiché l'ordine per gli array associativi sembra non definito.

In quanto tale, la via Ruby mi sembra più chiara e intuitiva. :)


Penso che non ci sia un modo giusto . Esistono molti modi diversi per iterare e ognuno ha una propria nicchia.

  • each è sufficiente per molti usi, poiché spesso non mi preoccupo degli indici.
  • each_ with _index agisce come Hash # ogni - si ottiene il valore e l'indice.
  • each_index - solo gli indici. Non lo uso spesso. Equivalente a "length.times".
  • map è un altro modo per iterare, utile quando si desidera trasformare un array in un altro.
  • select è l'iteratore da utilizzare quando si desidera scegliere un sottoinsieme.
  • inject è utile per generare somme o prodotti o raccogliere un singolo risultato.

Può sembrare molto da ricordare, ma non preoccuparti, puoi cavartela senza conoscerli tutti. Ma mentre inizi a imparare e ad usare i diversi metodi, il tuo codice diventerà più pulito e più chiaro e sarai sulla strada per raggiungere la maestria di Ruby.


Questo itererà attraverso tutti gli elementi:

array = [1, 2, 3, 4, 5, 6]
array.each { |x| puts x }

stampe:

1
2
3
4
5
6

Questo itererà attraverso tutti gli elementi dandoti il ​​valore e l'indice:

array = ["A", "B", "C"]
array.each_with_index {|val, index| puts "#{val} => #{index}" }

stampe:

A => 0
B => 1
C => 2

Non sono sicuro della tua domanda quale stai cercando.


Stavo cercando di creare un menu (in Camping e Markaby ) usando un hash.

Ogni elemento ha 2 elementi: un'etichetta di menu e un URL , quindi un hash sembrava giusto, ma l'URL '/' per 'Home' è sempre apparso per ultimo (come ci si aspetterebbe per un hash), quindi le voci del menu apparivano nella posizione sbagliata ordine.

Usare un array con each_slice fa il lavoro:

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

Aggiungere valori extra per ciascuna voce di menu (ad esempio, come un nome ID CSS) significa semplicemente aumentare il valore della sezione. Quindi, come un hash ma con gruppi costituiti da un numero qualsiasi di elementi. Perfezionare.

Quindi questo è solo per dire grazie per aver inavvertitamente suggerito una soluzione!

Ovvio, ma vale la pena affermare: suggerisco di verificare se la lunghezza dell'array è divisibile per il valore dello slice.


Usa each_with_index quando ti servono entrambi.

ary.each_with_index { |val, idx| # ...






loops