Các reduce()
phương pháp giảm một mảng các giá trị xuống chỉ còn một giá trị. Giá trị duy nhất được trả về có thể thuộc bất kỳ loại nào.
reduce()
giống như con dao quân đội Thụy Sĩ của các phương pháp mảng. Trong khi những người khác thích map()
và filter()
cung cấp chức năng cụ thể, reduce()
có thể được sử dụng để chuyển đổi một mảng đầu vào thành bất kỳ đầu ra nào bạn muốn, trong khi vẫn giữ nguyên mảng ban đầu.
cú pháp
const newValue = arr.reduce(function(accumulator, currentValue, index, array) {
// Do stuff with accumulator and currentValue (index, array, and initialValue are optional)
}, initialValue);
newValue
– số, mảng, chuỗi hoặc đối tượng mới được trả vềarr
– mảng đang được vận hànhaccumulator
– giá trị trả về của lần lặp trướccurrentValue
– mục hiện tại trong mảngindex
– chỉ mục của mục hiện tạiarray
– mảng ban đầu mà trên đóreduce()
được gọi làinitialValue
– một số, mảng, chuỗi hoặc đối tượng đóng vai trò là giá trị ban đầu cho đầu ra cuối cùng
ví dụ
ES5
var numbers = [1, 2, 3];
var sum = numbers.reduce(function(total, current) {
return total + current;
}, 0);
console.log(numbers); // [1, 2, 3]
console.log(sum); // 6
ES6
const numbers = [1, 2, 3];
const sum = numbers.reduce((total, current) => {
return total + current;
}, 0);
const sumOneLiner = numbers.reduce((total, current) => total + current, 0);
console.log(numbers); // [1, 2, 3]
console.log(sum); // 6
console.log(sumOneLiner); // 6
Tất cả về initialValue
initialValue
Cung cấp
Các initialValue
đối số là tùy chọn. Nếu được cung cấp, nó sẽ được sử dụng làm giá trị bộ tích lũy ban đầu (total
) trong lần gọi hàm gọi lại đầu tiên:
const numbers = [2, 3, 4];
const product = numbers.reduce((total, current) => {
return total * current;
}, 1);
console.log(product); // 24
Kể từ khi initialValue
của 1 được cung cấp sau chức năng gọi lại, reduce()
bắt đầu ở đầu mảng và đặt phần tử đầu tiên (2) làm giá trị hiện tại (current
). Sau đó, nó lặp qua phần còn lại của mảng, cập nhật giá trị bộ tích lũy và giá trị hiện tại trên đường đi.
initialValue
bỏ qua
Nếu initialValue
không được cung cấp, phép lặp sẽ bắt đầu ở phần tử thứ hai trong mảng (tại chỉ mục 1), với accumulator
bằng với phần tử đầu tiên trong mảng và currentValue
bằng phần tử thứ hai:
const numbers = [2, 3, 4];
const product = numbers.reduce((total, current) => {
return total * current;
});
console.log(product);
Trong ví dụ này, không initialValue
được cung cấp, vì vậy reduce()
đặt phần tử đầu tiên của mảng làm giá trị bộ tích lũy (total
bằng 2) và đặt phần tử thứ hai của mảng làm giá trị hiện tại (currentValue
bằng 3). Sau đó, nó lặp qua phần còn lại của mảng.
Khi giảm một chuỗi các chuỗi:
const strings = ['one', 'two', 'three'];
const numberString = strings.reduce((acc, curr) => {
return acc + ', ' + curr;
});
console.log(numberString); // "one, two, three"
Mặc dù thật dễ dàng để bỏ qua initialValue
đối số nếu của bạn reduce()
sẽ trả về một số hoặc một chuỗi đơn giản, bạn nên bao gồm một số nếu nó sẽ trả về một mảng hoặc đối tượng.
Trả lại một đối tượng
Việc chuyển đổi một mảng các chuỗi thành một đối tượng duy nhất hiển thị số lần mỗi chuỗi xuất hiện trong mảng rất đơn giản. Chỉ cần vượt qua một đối tượng trống ({}
) như initialValue
:
const pets = ["dog", "chicken", "cat", "dog", "chicken", "chicken", "rabbit"];
const petCounts = pets.reduce(function(obj, pet) {
if (!obj[pet]) {
// if the pet doesn't yet exist as a property of the accumulator object,
// add it as a property and set its count to 1
obj[pet] = 1;
} else {
// pet exists, so increment its count
obj[pet]++;
}
return obj; // return the modified object to be used as accumulator in the next iteration
}, {}); // initialize the accumulator as an empty object
console.log(petCounts);
/*
{
dog: 2,
chicken: 3,
cat: 1,
rabbit: 1
}
*/
Trả về và Mảng
Nói chung, nếu bạn định trả về một mảng, map()
thường là một lựa chọn tốt hơn. Nó báo cho trình biên dịch (và những người khác đang đọc mã của bạn) rằng mọi phần tử trong mảng ban đầu sẽ được chuyển đổi và trả về dưới dạng một mảng mới có độ dài bằng nhau.
Mặt khác, reduce()
chỉ ra rằng tất cả các phần tử của mảng ban đầu sẽ được chuyển đổi thành một giá trị mới. Giá trị mới đó có thể là một mảng, độ dài của mảng có thể khác với giá trị ban đầu.
Giả sử bạn có một danh sách mua sắm dưới dạng một chuỗi các chuỗi, nhưng bạn muốn xóa tất cả các loại thực phẩm mà bạn không thích khỏi danh sách. Bạn đã có thể sử dụng filter()
để lọc ra mọi thứ bạn không thích và map()
để trả về một chuỗi chuỗi mới hoặc bạn chỉ có thể sử dụng reduce()
:
const shoppingList = ['apples', 'mangoes', 'onions', 'cereal', 'carrots', 'eggplants'];
const foodsIDontLike = ['onions', 'eggplants'];
const newShoppingList = shoppingList.reduce((arr, curr) => {
if (!foodsIDontLike.includes(curr)) {
arr.push(curr);
}
return arr;
}, []);
console.log(newShoppingList); // ["apples", "mangoes", "cereal", "carrots"]
Đó là tất cả những gì bạn cần biết về reduce()
phương pháp. Giống như một con dao của quân đội Thụy Sĩ, nó không phải lúc nào cũng là công cụ tốt nhất cho công việc. Nhưng bạn sẽ rất vui khi có nó trong túi sau khi bạn thực sự cần.