Sự khác biệt chính giữa bản đồ và giảm


83

Tôi đã sử dụng cả hai phương pháp nhưng tôi khá bối rối về cách sử dụng của cả hai phương pháp.

Có phải bất cứ điều gì mapcó thể làm được nhưng reducekhông thể và ngược lại?

Lưu ý: Tôi biết cách sử dụng cả hai phương pháp mà tôi đang thắc mắc để biết sự khác biệt chính giữa phương pháp này và khi nào chúng ta cần sử dụng.

Câu trả lời:


228

Nguồn

Cả hai mapreducecó đầu vào là mảng và một hàm bạn xác định. Chúng bổ sung theo một cách nào đó: mapkhông thể trả về một phần tử duy nhất cho một mảng nhiều phần tử, trong khi reducesẽ luôn trả về bộ tích lũy mà bạn đã thay đổi cuối cùng.

map

Bằng cách sử dụng, mapbạn lặp lại các phần tử và đối với mỗi phần tử, bạn trả về một phần tử bạn muốn.

Ví dụ: nếu bạn có một mảng số và muốn lấy các ô vuông của chúng, bạn có thể làm như sau:

// 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

Sử dụng một mảng làm đầu vào, bạn có thể nhận một phần tử duy nhất (giả sử một Đối tượng, một Số hoặc một Mảng khác) dựa trên hàm gọi lại (đối số đầu tiên) nhận accumulatorcurrent_elementtham số:

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


Bạn nên chọn cái nào khi bạn có thể làm điều tương tự với cả hai? Hãy thử tưởng tượng mã trông như thế nào. Đối với ví dụ được cung cấp, bạn có thể tính toán mảng hình vuông như bạn đã đề cập, bằng cách sử dụng 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)

Bây giờ, nhìn vào những thứ này, rõ ràng là lần triển khai thứ hai trông đẹp hơn và nó ngắn hơn. Thông thường bạn sẽ chọn giải pháp sạch hơn, trong trường hợp này là như vậy map. Tất nhiên, bạn có thể làm điều đó reduce, nhưng tóm lại, hãy nghĩ rằng cái nào sẽ ngắn hơn và cuối cùng sẽ tốt hơn.


2
Được rồi, tôi đang thấy bạn Ví dụ về bản đồ nhưng tôi có thể làm điều tương tự với chức năng giảm, cái nào tốt và tại sao? Tạo mảng mới bằng cách giảm hoặc sửa đổi mảng hiện có với bản đồ.
Nishant Dixit

@NishantDixit Ý bạn là bạn có thể làm điều tương tự với điều reducegì? Bạn không thể, đó là những gì tôi đã cố gắng thể hiện trong những ví dụ đó.
Ionică Bizău

Tôi đang thêm phương thức giảm trong nhận xét dưới đây để tính bình phương của mảng đã cho và trả về mới.
Nishant Dixit

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

2
Khi chọn cái nào để sử dụng, mục đích là chìa khóa. Nếu cả hai đều có thể đạt được kết quả tương tự và vì sự khác biệt về hiệu suất là không đáng kể, hãy sử dụng hàm phù hợp với ý định của bạn như những gì Tadman đề cập bên dưới "Khi bạn" lập bản đồ ", bạn đang viết một hàm biến x với f (x) thành một hàm mới giá trị x1. Khi bạn "giảm", bạn đang viết một số hàm g (y) nhận mảng y và tạo ra mảng y1 ".
f0rfun

17

Nói chung "bản đồ" có nghĩa là chuyển đổi một loạt đầu vào thành một chuỗi đầu ra có độ dài bằng nhau trong khi "giảm" có nghĩa là chuyển đổi một loạt đầu vào thành một số lượng đầu ra nhỏ hơn .

Những gì mọi người có nghĩa là "map-Reduce" thường được hiểu là "chuyển đổi, có thể song song, kết hợp nối tiếp".

Khi bạn "ánh xạ", bạn đang viết một hàm có thể chuyển đổi xvới f(x)một số giá trị mớix1 . Khi bạn "giảm", bạn đang viết một số hàm g(y)lấy mảng yvà phát ra mảng y1. Chúng hoạt động trên các loại dữ liệu khác nhau và tạo ra các kết quả khác nhau.


Thực ra cả hai đều độc lập về kiểu dữ liệu chứ không phải "Chúng hoạt động trên các kiểu dữ liệu khác nhau ..." đúng không?
John Peters

8

Tôi nghĩ hình ảnh này sẽ trả lời cho bạn về sự khác biệt giữa những HOC đó nhập mô tả hình ảnh ở đây


6

Các map() chức năng trả về một mảng mới thông qua thông qua một chức năng trên mỗi phần tử trong mảng đầu vào.

Điều này khác với cách reduce()nhận một mảng và một hàm theo cùng một cách, nhưng hàm lấy2 đầu vào - một bộ tích lũy và một giá trị hiện tại.

Vì vậy, reduce()có thể được sử dụng như map()nếu bạn luôn .concatvào bộ tích lũy đầu ra tiếp theo từ một hàm. Tuy nhiên, nó được sử dụng phổ biến hơn để giảm kích thước của một mảng để lấy một chiều và trả về một giá trị duy nhất hoặc làm phẳng mảng hai chiều, v.v.


5

Chúng ta hãy xem xét từng cái một.

Bản đồ

Bản đồ nhận một lệnh gọi lại và chạy nó với mọi phần tử trên mảng nhưng điều làm cho nó trở nên độc nhất là nó tạo ra một mảng mới dựa trên mảng hiện có của bạn .

var arr = [1, 2, 3];

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

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

Giảm

Phương thức Reduce của đối tượng mảng được sử dụng để giảm mảng xuống một giá trị duy nhất .

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

Để hiểu sự khác biệt giữa bản đồ, bộ lọc và giảm bớt, hãy nhớ điều này:

  1. Cả ba phương thức này đều được áp dụng trên mảng vì vậy bất cứ khi nào bạn muốn thực hiện bất kỳ thao tác nào trên một mảng, bạn sẽ sử dụng các phương thức này.
  2. Cả ba đều theo cách tiếp cận chức năng và do đó mảng ban đầu vẫn giữ nguyên . Mảng gốc không thay đổi thay vào đó, một mảng / giá trị mới được trả về.
  3. Map trả về một mảng mới với số bằng. của các phần tử như có trong mảng ban đầu. Do đó, nếu mảng ban đầu có 5 phần tử thì mảng trả về cũng sẽ có 5 phần tử. Phương thức này được sử dụng bất cứ khi nào chúng ta muốn thực hiện một số thay đổi trên mỗi phần tử riêng lẻ của một mảng. Bạn có thể nhớ rằng mọi phần tử của mảng ann đang được ánh xạ tới một giá trị mới nào đó trong mảng đầu ra, do đó tên map Ví dụ:

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 trả về một mảng mới với số phần tử bằng / ít hơn mảng ban đầu. Nó trả về những phần tử trong mảng đã vượt qua một số điều kiện. Phương thức này được sử dụng khi chúng ta muốn áp dụng một bộ lọc trên mảng ban đầu do đó có tên filter. Ví dụ,

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

  1. Reducetrả về một giá trị duy nhất, không giống như một bản đồ / bộ lọc. Do đó, bất cứ khi nào chúng ta muốn chạy một hoạt động trên tất cả các phần tử của một mảng nhưng lại muốn một đầu ra duy nhất sử dụng tất cả các phần tử, chúng ta sử dụng reduce. Bạn có thể nhớ kết quả đầu ra của một mảng được giảm xuống một giá trị duy nhất do đó là tên reduce. Ví dụ,

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.