Harita ve azaltma arasındaki temel fark


86

Her iki yöntemi de kullandım ancak her iki yöntemin kullanımı konusunda oldukça kafam karıştı.

mapYapabilen ama reduceyapamayan ve tersi olan bir şey var mı ?

Not: Sorguladığım her iki yöntemi de nasıl kullanacağımı biliyorum, bu yöntem arasındaki temel farkı ve ne zaman kullanmamız gerektiğini.

Yanıtlar:


237

Kaynak

Hem mapve reducegirdi olarak dizi ve tanımlayan bir işlevi vardır. Bir şekilde tamamlayıcıdırlar: mapbirden çok öğeden oluşan bir dizi için tek bir öğe reducedöndüremezken, sonunda değiştirdiğiniz akümülatörü her zaman döndürecektir.

map

mapSizi kullanarak öğeleri yinelersiniz ve her öğe için istediğiniz bir öğeyi döndürürsünüz.

Örneğin, bir dizi sayıya sahipseniz ve karelerini almak istiyorsanız, bunu yapabilirsiniz:

// A function which calculates the square
const square = x => x * x

// Use `map` to get the square of each number
console.log([1, 2, 3, 4, 5].map(square))

reduce

Bir diziyi girdi olarak kullanarak, accumulatorve current_elementparametrelerini alan geri çağırma işlevine (ilk bağımsız değişken) dayalı olarak tek bir öğe (diyelim ki bir Nesne veya Sayı veya başka bir Dizi) elde edebilirsiniz :

const numbers = [1, 2, 3, 4, 5]

// Calculate the sum
console.log(numbers.reduce(function (acc, current) {
  return acc + current
}, 0)) // < Start with 0

// Calculate the product
console.log(numbers.reduce(function (acc, current) {
  return acc * current
}, 1)) // < Start with 1


Her ikisiyle de aynı şeyi yapabileceğiniz zaman hangisini seçmelisiniz? Kodun nasıl göründüğünü hayal etmeye çalışın. Verilen örnek için, aşağıdaki kullanarak squares dizisini bahsettiğiniz gibi hesaplayabilirsiniz reduce:

// Using reduce
[1, 2, 3, 4, 5].reduce(function (acc, current) {
    acc.push(current*current);
    return acc;
 }, [])

 // Using map
 [1, 2, 3, 4, 5].map(x => x * x)

Şimdi, bunlara baktığımızda, açıkça görülüyor ki ikinci uygulama daha iyi görünüyor ve daha kısa. Genellikle, bu durumda daha temiz olan çözümü seçersiniz map. Tabii ki bunu yapabilirsiniz reduce, ama kısaca, hangisinin daha kısa olacağını ve sonunda daha iyi olacağını düşünün.


2
Tamam Harita örneğini görüyorum ama aynı şeyi azalt işleviyle de yapabileceğim şey hangisi iyi ve neden? Mevcut diziyi harita ile azaltarak veya değiştirerek yeni dizi oluşturma.
Nishant Dixit

@NishantDixit Aynı şeyi onunla yapabileceğinle ne demek istiyorsun reduce? Yapamazsın, bu örneklerde göstermeye çalıştığım şey bu.
Ionică Bizău

Verilen kareyi hesaplayan ve yeni dizi döndüren aşağıdaki yoruma azaltma yöntemi ekliyorum.
Nishant Dixit

console.log([1, 2, 3, 4, 5].reduce(function (acc, current) { acc.push( current = current*current); return acc; }, []))
Nishant Dixit

2
Hangisinin kullanılacağını seçerken amaç anahtardır. Her ikisi de benzer sonuçlar elde edebiliyorsa ve performans farkı ihmal edilebilir düzeydeyse, Tadman'ın aşağıda bahsettiği gibi amacınıza uygun işlevi kullanın "Eşleme yaptığınızda" x'i f (x) ile yeni bir fonksiyona dönüştüren bir işlev yazıyorsunuz demektir. değer x1. "Azalttığınızda" y dizisini alan ve y1 dizisini yayınlayan bir g (y) işlevi yazarsınız.
f0rfun

18

Genel olarak "eşleme", bir dizi girdiyi eşit uzunlukta çıktı dizisine dönüştürmek anlamına gelirken "azalt", bir dizi girdiyi daha az sayıda çıktıya dönüştürmek anlamına gelir .

İnsanların "haritayı azalt" ile kastettiği şey, genellikle "dönüşüm, muhtemelen paralel olarak, seri olarak birleştir" anlamına gelir.

Eğer "harita" zaman, bir işlev yazıyoruz dönüşümler xile f(x)bazı yeni değere x1. "Azalttığınızda" g(y), dizi alan yve dizi yayan bir işlev yazarsınız y1. Farklı veri türleri üzerinde çalışırlar ve farklı sonuçlar üretirler.


Aslında, her ikisi de veri türünden bağımsızdır, "Farklı veri türleri üzerinde çalışırlar ..." değil mi?
JWP

13

Sanırım bu resim, bu HOC arasındaki fark hakkında size cevap verecek görüntü açıklamasını buraya girin


6

map()Fonksiyon giriş dizisindeki her eleman üzerinde bir işlevi geçen üzerinden yeni bir dizi döner.

Bu, reduce()bir dizi ve bir işlevi aynı şekilde alandan farklıdır , ancak işlev 2girdileri alır - bir toplayıcı ve bir akım değeri.

Bu nedenle reduce(), map()her zaman .concattoplayıcıya bir işlevden sonraki çıktı gibi kullanılabilir . Bununla birlikte, bir dizinin boyutlarını küçültmek için daha yaygın olarak kullanılır, böylece ya bir boyutlu alıp tek bir değer döndürür ya da iki boyutlu bir diziyi düzleştirir vb.


5

Bu ikisine tek tek göz atalım.

Harita

Harita bir geri arama alır ve dizideki her öğeye karşı çalıştırır, ancak onu benzersiz kılan , mevcut dizinize göre yeni bir dizi oluşturmasıdır .

var arr = [1, 2, 3];

var mapped = arr.map(function(elem) {
    return elem * 10;
})

console.log(mapped); // it genrate new array

Azalt

Diziyi tek bir değere düşürmek için dizi nesnesinin azaltma yöntemi kullanılır .

var arr = [1, 2, 3];

var sum = arr.reduce(function(sum, elem){
    return sum + elem;
})

console.log(sum) // reduce the array to one single value


3

Harita, filtreleme ve azaltma arasındaki farkı anlamak için şunu unutmayın:

  1. Her üç yöntem de diziye uygulanır, böylece bir dizi üzerinde herhangi bir işlem yapmak istediğinizde, bu yöntemleri kullanacaksınız.
  2. Üçü de işlevsel yaklaşımları takip eder ve bu nedenle orijinal dizi aynı kalır . Orijinal dizi değişmez, bunun yerine yeni bir dizi / değer döndürülür.
  3. Map no ile eşit olan yeni bir dizi döndürür. orijinal dizide olduğu gibi öğeler . Bu nedenle, orijinal dizi 5 öğeye sahipse, döndürülen dizi de 5 öğeye sahip olacaktır. Bu yöntem, bir dizinin her bir öğesinde bir değişiklik yapmak istediğimizde kullanılır. Ann dizisinin her öğesinin çıktı dizisindeki bazı yeni değerlerle eşleştirildiğini hatırlayabilirsiniz, bu nedenle adı map Örneğin

var originalArr = [1,2,3,4]
//[1,2,3,4]
var squaredArr = originalArr.map(function(elem){
  return Math.pow(elem,2);
});
//[1,4,9,16]

  1. Filter orijinal diziye eşit / daha az sayıda öğeye sahip yeni bir dizi döndürür . Dizideki bazı koşulları geçen öğeleri döndürür. Bu yöntem, orijinal diziye bir filtre uygulamak istediğimizde kullanılır, dolayısıyla adı filter. Örneğin,

var originalArr = [1,2,3,4]
//[1,2,3,4]
var evenArr = originalArr.filter(function(elem){
  return elem%2==0;
})
//[2,4]

  1. Reducebir harita / filtreden farklı olarak tek bir değer döndürür. Bu nedenle, bir dizinin tüm elemanları üzerinde bir işlem çalıştırmak istediğimizde, ancak tüm elemanları kullanarak tek bir çıktı istediğimizde, kullanırız reduce. Bir dizinin çıktısının tek bir değere, dolayısıyla adın indirildiğini hatırlayabilirsiniz reduce. Örneğin,

var originalArr = [1,2,3,4]
//[1,2,3,4]
var sum = originalArr.reduce(function(total,elem){
  return total+elem;
},0)
//10

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.