aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
SAVED POSTS
aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
aedev.net
No Result
View All Result
Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Array.reduce thiếu initialValue: mảng rỗng lỗi, một phần tử không gọi callback

Suong Nguyen by Suong Nguyen
06/11/2026
in Phỏng vấn
0
585
SHARES
3.2k
VIEWS
Summarize with ChatGPTShare to Facebook

Một hàm tính tổng chạy ổn với hai số nhưng lỗi khi bộ lọc trả về mảng rỗng. Khi chỉ còn một phần tử, log trong callback lại không xuất hiện. Trước khi sửa bằng cách thêm 0, hãy xác định reduce đang lấy accumulator đầu tiên từ đâu.

Bài đối chiếu MDN ngày 06/11/2026 và chạy các ví dụ bằng Node.js 24.18.1. Các mảng trong demo là mảng đặc, không có getter, Proxy hoặc thao tác sửa cấu trúc trong callback. Không có benchmark hay kết luận về mọi dạng dữ liệu có thể gọi reduce.

Hai cách bắt đầu phép gộp

Nếu có initialValue, nó là accumulator đầu tiên và callback xử lý từ phần tử đầu. Nếu không có, reduce lấy phần tử đầu làm accumulator rồi bắt đầu callback từ phần tử tiếp theo.

Với mảng rỗng và không có initialValue, không có gì để dùng làm accumulator nên reduce ném TypeError. Với đúng một phần tử và không có initialValue, nó có thể trả ngay phần tử đó mà không gọi callback. Đây là khác biệt cần giải thích được trước khi đoán số lần log.

1. Ghi lại chỉ số callback trên mảng số

Lưu đoạn sau vào file .cjs rồi chạy Node. Assertions xác nhận cả giá trị cuối và các chỉ số thật sự đã được duyệt:

const assert = require('node:assert/strict');
const withoutInitial = [];
const withInitial = [];

const firstSum = [2, 3].reduce((acc, value, index) => {
  withoutInitial.push({acc, value, index});
  return acc + value;
});
const secondSum = [2, 3].reduce((acc, value, index) => {
  withInitial.push({acc, value, index});
  return acc + value;
}, 0);

assert.equal(firstSum, 5);
assert.equal(secondSum, 5);
assert.deepEqual(withoutInitial, [{acc: 2, value: 3, index: 1}]);
assert.deepEqual(withInitial, [
  {acc: 0, value: 2, index: 0},
  {acc: 2, value: 3, index: 1},
]);
assert.throws(() => [].reduce((acc, value) => acc + value), TypeError);
assert.equal([].reduce((acc, value) => acc + value, 0), 0);

let calls = 0;
const single = [7].reduce((acc, value) => {
  calls += 1;
  return acc + value;
});
assert.equal(single, 7);
assert.equal(calls, 0);
console.log('initial value and callback indices verified');

Hai phép gộp cùng trả 5 nhưng có đường chạy callback khác nhau. Vì thế, chỉ kiểm tra tổng cuối sẽ không giúp bạn phát hiện assumption rằng callback luôn nhận mọi phần tử.

Không đặt một bước validation bắt buộc cho từng phần tử vào callback rồi bỏ initialValue. Trường hợp một phần tử có thể đi qua mà callback không chạy. Nếu cần kiểm tra toàn bộ đầu vào, thực hiện việc đó rõ ràng trước hoặc bảo đảm cấu trúc phép gộp phù hợp.

2. InitialValue còn định nghĩa kiểu accumulator

Ví dụ độc lập sau cộng trường amount của các dòng. Accumulator được khai báo là số bằng cách bắt đầu từ 0:

const assert = require('node:assert/strict');

function totalAmount(rows) {
  if (!Array.isArray(rows) || !rows.every(row =>
    row !== null && typeof row === 'object' &&
    Number.isFinite(row.amount)
  )) {
    throw new TypeError('Expected rows with finite numeric amounts');
  }
  return rows.reduce((sum, row) => sum + row.amount, 0);
}

assert.equal(totalAmount([]), 0);
assert.equal(totalAmount([{amount: 7}]), 7);
assert.equal(totalAmount([{amount: 7}, {amount: 3}]), 10);
assert.throws(() => totalAmount([{amount: '7'}]), TypeError);
assert.throws(() => totalAmount([{amount: NaN}]), TypeError);
console.log('numeric accumulator verified');

Nếu bỏ 0, phần tử đầu là object sẽ được dùng làm accumulator. Nhưng callback đang kỳ vọng sum là số. Lỗi không chỉ nằm ở ca mảng rỗng: kiểu của giá trị bắt đầu cũng không còn đúng với phép cộng mà bạn viết.

Validation mẫu dành cho mảng đặc và object dữ liệu đơn giản; không coi đây là schema validator cho object tùy ý. Nếu dữ liệu có quy tắc số nguyên, không âm hoặc đơn vị tiền tệ, bổ sung hợp đồng tương ứng thay vì mặc định Number.isFinite đã đủ.

Cách trả lời và kiểm tra khi phỏng vấn

Nêu accumulator ban đầu, chỉ số callback đầu tiên và giá trị trả về trong ba ca: rỗng, một phần tử, hai phần tử. Sau đó chỉ ra initialValue phù hợp với kết quả cần tạo: số, chuỗi, mảng hay một cấu trúc khác.

Đừng thêm 0 theo thói quen cho mọi reduce. Nếu đang xây danh sách, 0 không phải accumulator phù hợp. Nếu dùng object hoặc mảng rồi sửa nó trong callback, nhớ trả accumulator cho lần lặp tiếp theo và xác định nó có đang được chia sẻ ra ngoài hay không.

Một vòng lặp rõ ràng cũng là lựa chọn hợp lệ nếu phép gộp khó đọc. Điều cần bảo vệ là hợp đồng dữ liệu và các ca biên, không phải việc mọi bài toán xử lý mảng đều phải được viết bằng reduce.

Nguồn tham khảo

  • MDN: reduce, initialValue và các ca biên

Tags: ArrayJavaScriptPhỏng vấn
SummarizeShare234
Suong Nguyen

Suong Nguyen

Related Stories

Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Destructuring default: vì sao undefined nhận mặc định còn null thì không?

by Suong Nguyen
05/11/2026
0

Phân biệt default của thuộc tính với default của cả tham số và kiểm tra các trường hợp null, undefined, 0 và chuỗi rỗng.

Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Array.isArray và instanceof: mảng từ realm khác được kiểm tra thế nào?

by Suong Nguyen
04/11/2026
0

Tạo một mảng trong Node vm để kiểm chứng Array.isArray nhận ra mảng dù instanceof với Array của ngữ cảnh ngoài trả false.

Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Vì sao map(parseInt) biến index thành radix?

by Suong Nguyen
03/11/2026
0

Theo dõi arguments của Array.map để giải thích kết quả 10, NaN, 2 và viết wrapper chốt radix thay vì truyền thẳng parseInt.

Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Object.freeze chỉ đóng băng nông: giải thích bằng assertion

by Suong Nguyen
02/11/2026
0

Theo dõi reference trước và sau Object.freeze để giải thích vì sao object con vẫn đổi được, rồi kiểm tra lỗi ghi trong strict mode.

0 0 votes
Article Rating
Subscribe
Login
Notify of
guest
guest
0 Comments
Oldest
Newest Most Voted
AE Dev

AE Dev mang đến các bài viết về lập trình, mobile app, backend, frontend, WordPress và công nghệ, phù hợp cho developer muốn học hỏi và cập nhật kiến thức thực tế.

Recent Posts

  • React Native ActivityIndicator: dừng spinner có cần bỏ cả vùng giữ chỗ?
  • Array.reduce thiếu initialValue: mảng rỗng lỗi, một phần tử không gọi callback
  • Android SharedPreferences.apply: đọc lại được chưa chứng minh đã ghi xong xuống đĩa

Categories

  • AI
  • Backend
  • Đánh giá
  • DevOps
  • Flutter
  • Hướng dẫn
  • Lập trình Mobile
  • Phỏng vấn
  • React Native
  • Uncategorized

Weekly Newsletter

  • Buy JNews
  • Support Forum
  • Pre-sale Question
  • Contact Us

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • AI
  • Mobile
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
  • Flutter

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

wpDiscuz
0
0
Would love your thoughts, please comment.x
()
x
| Reply