- Konu sahibi
- #1
JavaScript'te
Buradaki
Başlangıç değeri verilirse ilk çağrıda accumulator bu değer, currentValue ise dizinin ilk mevcut elemanı olur; boş hücreler atlanır. Başlangıç değeri verilmezse reduce ilk mevcut elemanı başlangıç sonucu kabul eder ve sonraki mevcut elemandan devam eder. Bu nedenle özellikle sayı toplama, nesne oluşturma ve boş kalabilecek dizilerde başlangıç değeri açıkça verilmelidir.
Aşağıdaki tam örnek, bir dizideki sayıları toplar ve sonucu konsola yazar:
Beklenen çıktı:
İşleyiş şöyledir: başlangıç değeri
Bu örnekte callback içinde
Kararı şu sırayla verebilirsiniz:
reduce seçimini şu kısa karşılaştırma kolaylaştırır:
reduce ile dizi oluştururken accumulator'ı değiştirmek yerine yeni bir dizi döndürmek daha okunaklı olabilir; ancak büyük dizilerde her adımda kopyalama gereksiz maliyet oluşturabilir. Bu nedenle performans önemliyse ve kodun okunabilirliği korunabiliyorsa kontrollü mutasyon veya klasik
Başlangıç değerini yanlış türde vermek, örneğin sayısal toplam için
reduce(), bir dizinin elemanlarını sırayla işleyip hepsinden tek bir sonuç üretmek için kullanılan dizi metodudur. Bu sonuç sayı, metin, nesne, başka bir dizi veya herhangi bir JavaScript değeri olabilir. Örneğin bir sayı dizisini toplamak, alışveriş sepetinin toplamını hesaplamak ya da kayıtları kategori bazında gruplamak için kullanılır. Orijinal dizi değiştirilmez; ancak callback içinde accumulator olarak kullanılan nesne veya dizi doğrudan değiştirilirse bu ayrı bir mutasyon oluşturur.Çalışma mantığı ve temel sözdizimi
Kod:
dizi.reduce((accumulator, currentValue, index, array) => {
return yeniAccumulator;
}, initialValue);
Buradaki
accumulator, her adımın bir sonraki adıma devrettiği değerdir. currentValue o an işlenen dizi elemanıdır. index elemanın sıra numarasını, array ise üzerinde çalışılan diziyi belirtir. initialValue başlangıç accumulator değeridir.Başlangıç değeri verilirse ilk çağrıda accumulator bu değer, currentValue ise dizinin ilk mevcut elemanı olur; boş hücreler atlanır. Başlangıç değeri verilmezse reduce ilk mevcut elemanı başlangıç sonucu kabul eder ve sonraki mevcut elemandan devam eder. Bu nedenle özellikle sayı toplama, nesne oluşturma ve boş kalabilecek dizilerde başlangıç değeri açıkça verilmelidir.
Somut örnek: toplam hesaplama
Aşağıdaki tam örnek, bir dizideki sayıları toplar ve sonucu konsola yazar:
Kod:
const prices = [120, 80, 50];
const total = prices.reduce((sum, price) => {
return sum + price;
}, 0);
console.log(total);
Beklenen çıktı:
Kod:
250
İşleyiş şöyledir: başlangıç değeri
0 olur; ilk adımda 0 + 120, sonraki adımda 120 + 80, son adımda ise 200 + 50 hesaplanır. Son callback dönüşü total değişkenine aktarılır.Bu örnekte callback içinde
sum yerine price yazmak veya toplamı döndürmemek sonucu bozar. Callback her adımda yeni accumulator değerini döndürmelidir. Beklenen çıktı yerine undefined görürseniz genellikle return eksiktir; ilk elemana işlem uygulanmıyorsa da başlangıç değerinin verilmemiş olup olmadığını kontrol edin.| İhtiyaç | Uygun metot | Sonuç |
|---|---|---|
| Her elemanı dönüştürmek | map() | Genellikle aynı uzunlukta yeni dizi |
| Bazı elemanları seçmek | filter() | Daha kısa veya aynı uzunlukta yeni dizi |
| Tüm elemanlardan tek sonuç üretmek | reduce() | Herhangi bir tek değer |
reduce ne zaman kullanılmalı?
Kararı şu sırayla verebilirsiniz:
- Bir diziden tek bir sonuç üretip üretmediğinizi belirleyin. Toplam, ortalama için gerekli toplam, gruplanmış nesne veya birleştirilmiş dizi buna örnektir.
- Accumulator'ın başlangıç türünü seçin. Toplam için
0, metin için boş metin, sonuç nesnesi için{}, sonuç dizisi için[]kullanın. - Her callback çağrısında güncel değeri hesaplayıp mutlaka döndürün.
- Boş dizi ihtimalini test edin. Başlangıç değeri verilmişse reduce başlangıç değerini döndürür; verilmemişse boş dizi TypeError oluşturur. Yalnız boş hücrelerden oluşan seyrek dizi de başlangıçsızsa aynı sorunu taşır.
- Kod tek bir dönüşüm veya filtreleme yapıyorsa reduce yerine amaca özel
map()veyafilter()kullanmayı değerlendirin.
reduce seçimini şu kısa karşılaştırma kolaylaştırır:
reduce ile dizi oluştururken accumulator'ı değiştirmek yerine yeni bir dizi döndürmek daha okunaklı olabilir; ancak büyük dizilerde her adımda kopyalama gereksiz maliyet oluşturabilir. Bu nedenle performans önemliyse ve kodun okunabilirliği korunabiliyorsa kontrollü mutasyon veya klasik
for...of döngüsü daha uygun olabilir. Ayrıca reduce iç içe ve uzun işlemlerle kullanıldığında kodu takip etmek zorlaşır; karmaşık işlemleri küçük, adlandırılmış fonksiyonlara ayırın.Sık yapılan hatalar
Başlangıç değerini yanlış türde vermek, örneğin sayısal toplam için
'' kullanmak, beklenmeyen birleştirme sonuçlarına yol açabilir. Accumulator olarak nesne kullanırken callback'in sonunda nesneyi döndürmemek de sonraki adımda hataya neden olur. Ayrıca reduce doğrudan asenkron işlemleri sıraya koyan bir araç değildir; Promise kullanan işlemlerde accumulator'ın Promise olup olmadığını açıkça yönetmeniz gerekir.