Articles

porozumění Ruby ‚ s #inject / #reduce enumerable methods in under 5 minutes

Chcete-li začít, tato metoda vyžaduje pole a dva argumenty, pokud jsou definovány. To může být zobrazil jako následující:

.inject { |memo, value| 
#more lines of code here
}.reduce { |memo, value|
#more lines of code here
}

všimněte si, že proměnnámemomemo stojan pro paměti. Tato proměnná je nezbytná, protože ukládá, jaká data chcete, aby si tato metoda pamatovala, zatímco prochází po celém poli, ale lze ji pojmenovat, co chcete, protože je to jen proměnná.

budu se odkazovat na to jakomemo v celém tomto vysvětlení.

memo lze zadat počáteční hodnotu, ale není nutné ji mít. Pokud výchozí hodnota není definována, pak memo vezme první hodnotu pole.

### The starting value for memo is 5
.inject(5) { |memo, value|
#more lines of code here
}
### The starting value for memo is 1 (first value of the array)
.reduce { |memo, value|
#more lines of code here
}

#inject#reducevrátí vždy jeden datový objekt — data memo drží na konci. Jak již bylo řečeno, memo musí být změněn a vrácen, protože je smyčkovaný, jinak zůstane na stejné hodnotě.

Nyní, že máme sémantika dolů, jdu se projít nějaké příklady, když jsem zjistil, #inject#reduce užitečné.

Příklad 1: Pomocí #inject / #snížit aplikovat numerické operace

nejběžnější způsob použití této metody je, když vzhledem k tomu, pole celých čísel, a budete muset použít číselná operace na celé pole. V tomto příkladu ukážu, jak najít součet celého pole.

#inject#reduce , bude znázorněn jako takový:

.reduce { |memo, value|
memo += value
} ## The following is to illustrate how this method was traversed
~> 1 += 2 #memo returns 3
~> 3 += 3 #memo returns 6
~> 6 += 4 #memo returns 10
~> 10 += 5 #memo returns 15#=> 15

Protože to je docela běžný způsob, jak používat #inject#reduce , tam je zkratka metodu můžete použít, pokud si jen chcete použít číselné operace v celé své pole tím to následujícím způsobem:

## This is for product, with no initial value stated
.inject(:*)
#=> 120 ### This is for sum, with an initial value of 5
.reduce(5, :+)
#=> 20

Příklad 2: Pomocí #inject/ #snížit najít nejdelší řetězec

Pro tento příklad, řekněme, že jste vzhledem k tomu, pole řetězců a máte najít nejdelší řetězec v poli.

Pro tento případ, #inject#reduce se zobrazí jako:

sentences = sentences.inject{ |memo, sentence| 
if memo.size < sentence.size
memo = sentence
else
memo
end
}
#=> "There are jumping lizards on the fountain"

zlomit to dolů: Protože nechceme inicializovat memo s hodnotou, to bude trvat první objekt v poli, sentences v tomto příkladu. V naší metodě jsme mít if prohlášení, že jen srovnává naše memo délka sentence délka.

toto if prohlášení je místo, kde se kouzlo děje: pokud sentence je delší než jeden uložený v memo pak jsme re-přiřadit poznámku sentence; jinak jen vrátit stejnou hodnotu.

naše memo, hodnota se bude průběžně aktualizovat s jižsentence#inject#reduce vrátí memo proměnné na konci.

Pokud chcete vidět každý krok ilustrovaný, můžete jej spustit v Repl.it Chcete-li vidět na vlastní oči.

sentences = sentences.inject { |memo, sentence|
puts "Memo length is: #{memo.length}\nSentence length is: #{sentence.length}"
if memo.length < sentence.length
puts "Our sentence is longer"
memo = sentence
else
puts "Our memo is longer"
memo
end
puts "Our memo is: #{memo}\n \n"
memo
}

příklad #3: Použití # inject / #reduce k nalezení nejvíce opakujícího se čísla v poli

Nyní, když jsme tuto metodu praktikovali různými způsoby, udělejme podobný příklad. Řekněme, že jste dostali náhodné pole čísel a chcete zjistit, které číslo se opakuje více.

pro tento případ můžete použít#inject#reduce like so:

numbers = numbers.reduce { |memo, number|
if numbers.count(memo) <= numbers.count(number)
memo = number
else
memo
end
}

Nyní, tato logika je podobná tomu, co jsme dělali v Příkladu 2, jediný rozdíl je v našem případě prohlášení, budeme používat #count naše počáteční pole najít a obchod, který má hodnotu větší nebo rovno count. Tímto způsobem se nám vrací pouze číslo, které má na konci největší počet.