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ámemo
memo
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
#reduce
vrá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.