Đưa kết quả Array.find vào if có thể làm mất một kết quả hợp lệ như 0, false hoặc chuỗi rỗng. Còn nếu undefined là dữ liệu được phép, so sánh kết quả với undefined cũng chưa phân biệt được có tìm thấy hay không. Cần tách câu hỏi “giá trị là gì?” khỏi “có phần tử khớp không?”.
1. Kết quả falsy vẫn có thể là kết quả tìm thấy
const counts = [0, 5, 10];
const match = counts.find(value => value === 0);
console.log(match); // 0
console.log(Boolean(match)); // false
console.log(counts.some(value => value === 0)); // true
find trả phần tử đầu tiên làm predicate cho kết quả truthy; nếu không có thì trả undefined, theo MDN Array.find. Giá trị phần tử không cần truthy. Điều kiện tìm value === 0 đã khớp, nhưng if (match) lại kiểm tra tính truthy của số 0.
Nếu nghiệp vụ chỉ hỏi có số lượng bằng 0 không, some thể hiện mục đích trực tiếp hơn. Nếu cần lấy dữ liệu, phải giữ cả trạng thái khớp và giá trị khi miền dữ liệu cho phép những giá trị falsy.
2. undefined còn có thể là phần tử hợp lệ
const values = [undefined, 'ready'];
const predicate = value => value === undefined;
console.log(values.find(predicate)); // undefined
console.log([].find(predicate)); // undefined
console.log(values.findIndex(predicate)); // 0
console.log([].findIndex(predicate)); // -1
Cùng kết quả undefined nhưng một lần có khớp và một lần không. findIndex trả vị trí hoặc -1 nên có thể biểu diễn khác biệt này. Khi dùng chỉ mục, so sánh rõ với -1; vị trí 0 không phải tín hiệu thất bại.
Với mảng thưa thông thường, find và findIndex cũng có thể đọc ô trống như undefined. Nếu chỉ muốn phần tử được gán tường minh, cần kiểm tra sự tồn tại của chỉ mục hoặc cấm mảng thưa ở contract. Ví dụ bài này dùng mảng đặc để tránh nhập nhằng đó.
3. Trả cờ found cùng với giá trị
function findValue(values, predicate) {
if (!Array.isArray(values) || typeof predicate !== 'function') {
throw new TypeError('expected an array and a predicate');
}
const index = values.findIndex((value, index) => {
const matched = predicate(value, index);
if (typeof matched !== 'boolean') {
throw new TypeError('predicate must return a boolean');
}
return matched;
});
return index === -1
? { found: false }
: { found: true, index, value: values[index] };
}
const hit = findValue([undefined], value => value === undefined);
console.log(hit.found); // true
console.log(hit.value === undefined); // true
console.log(findValue([], () => true).found); // false
Helper dành cho mảng dữ liệu thông thường và predicate đồng bộ, không sửa mảng trong lúc tìm. Nó yêu cầu predicate trả boolean tường minh, nghiêm hơn phương thức gốc chấp nhận mọi giá trị truthy/falsy. Nếu callback được gọi và trả Promise hoặc số, helper ném TypeError thay vì diễn giải ngầm.
Với mảng rỗng, callback không chạy nên kiểm tra kiểu kết quả callback cũng không chạy. Không dùng helper để chứng minh một callback bất kỳ sẽ luôn trả boolean. Callback async hoặc tác vụ có thể reject cần một luồng await riêng; không truyền chúng vào helper đồng bộ này.
4. Giá trị object vẫn là tham chiếu
Khi phần tử khớp là object, trường value trỏ tới object trong mảng. Sửa thuộc tính của nó có thể thay đổi dữ liệu nguồn. Cờ found giải quyết cách biểu diễn kết quả, không tạo bản sao độc lập và không kiểm tra schema của bản ghi.
Không gọi some rồi find với cùng một predicate có tác dụng phụ để suy ra một kết quả thống nhất. Hai lần duyệt có thể quan sát trạng thái khác nhau và chạy công việc lặp lại. Chọn một lần tìm trả đủ thông tin mà bên gọi cần.
5. Checklist cho kết quả tìm kiếm
- Miền dữ liệu có cho phép 0, false, chuỗi rỗng hoặc undefined?
- Bên gọi cần boolean, chỉ mục hay chính phần tử?
- Đã thử phần tử đầu tiên và danh sách không khớp?
- Có cho phép ô trống hoặc callback sửa mảng khi tìm?
- Callback là đồng bộ và trả đúng kiểu kết quả đã thỏa thuận?
Sáu khối mã Việt–Anh đã chạy bằng Node.js; kiểm tra thêm giá trị falsy, nhiều kết quả khớp, tham chiếu object và callback trả sai kiểu. Chưa tích hợp API hoặc giao diện thực tế.




Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.