2012-09-30 9 views
5

La differenza tra Enumerable#each e Enumerable#map è se restituisce il destinatario o il risultato mappato. Tornando al ricevitore è banale e di solito non è necessario continuare una catena di metodi dopo each come each{...}.another_method (probabilmente non ho visto tale caso. Anche se si desidera tornare al ricevitore, è possibile farlo con tap). Quindi penso che tutti o quasi tutti i casi in cui viene utilizzato lo standard Enumerable#each possono essere sostituiti da Enumerable#map. Ho sbagliato? Se ho ragione, qual è lo scopo di each? map è più lento di each?Non è possibile sostituire tutti o la maggior parte dei casi di `each` con` map`?

Edit: So che c'è una pratica comune utilizzare each quando non si è interessati al valore di ritorno. Non mi interessa sapere se tale pratica esista, ma mi interessa sapere se tale pratica abbia un senso diverso dal punto di vista della convenzione.

+1

Capisci che 'each' è una parte fondamentale di Enumerable mentre' map' non lo è, giusto? ["La classe deve fornire un metodo' each', che produce i membri successivi della collezione. "] (Http://ruby-doc.org/core-1.9.3/Enumerable.html). –

+0

@muistooshort Non ne sono consapevole. Ci penserò. Grazie. – sawa

+2

Provate ad implementare 'map' in termini di' each' e quindi 'each' in termini di' map', che potrebbe darvi un po 'di intuizione. –

risposta

5

La scelta tra map o each deve essere decisa dal risultato finale desiderato: un nuovo array o nessun nuovo array. Il risultato di map può essere enorme e/o sciocco:

p ("aaaa".."zzzz").map{|word| puts word} #huge and useless array of nil's 
+0

Se è lento, capisco che non dovrei usarlo, ma perché è sciocco? Non lo capisco affatto. Ruby ha ereditato da Lisp l'idea che ogni valutazione restituisca un valore. – sawa

+3

Il risultato di questa 'map' è un array con 456976 nil (' puts' restituisce un nullo). Viene scartato dopo essere stato creato. L'uso di 'each' non lo avrebbe affatto creato, risparmiando memoria. (Codice leggermente modificato) – steenslag

+0

Questo era quello che sto chiedendo. Se fa differenza per quanto riguarda le prestazioni. – sawa

2

Sono d'accordo con quello che hai detto. Enumerable#each restituisce semplicemente l'oggetto originale su cui è stato chiamato mentre Enumerable#map imposta l'elemento corrente che viene iterato sul valore restituito del blocco e quindi restituisce un nuovo oggetto con tali modifiche.

Poiché Enumerable#each restituisce semplicemente l'oggetto originale stesso, può essere molto preferibile rispetto allo map quando si tratta di casi in cui è necessario semplicemente iterare o attraversare più elementi.

In effetti, Enumerable#each è un modo semplice e universale di fare un ciclo iterativo tradizionale, ed è molto preferito per i loop in Ruby.

+0

Non sono sinceramente interessato a come gli altri preferiscono un metodo rispetto all'altro. Mi interessa sapere se abbia senso avere un uso distinto di "ciascuno". – sawa

6

La differenza tra map e each è più importante se si restituisce un nuovo array e l'altro no. L'importante differenza sta nel modo in cui comunicano il tuo intento.

Quando si utilizza each, il codice dice "Sto facendo qualcosa per ogni elemento". Quando si utilizza map, il codice dice "Sto creando un nuovo array trasformando ciascun elemento."

Così mentre è possibile utilizzare map al posto di each, malgrado le prestazioni, il codice starebbe mentendo sul suo intento a chiunque lo stia leggendo.

0

Quando si compongono questi enumaroli è possibile vedere la differenza significativa tra map e each.

Per esempio è necessario per ottenere nuovi array con indixes in esso:

array.each.with_index.map { |index, element| [index, element] } 

O per esempio è sufficiente applicare un metodo a tutti gli elementi di matrice e la stampa risultato senza modificare la matrice originale:

m = 2.method(:+) 

[1,2,3].each { |a| puts m.call(a) } #=> prints 3, 4, 5 

E ce ne sono molti altri esempi in cui la differenza tra each e map è la chiave importante nel codice di scrittura in stile funzionale.

Problemi correlati