Mình thấy rằng câu hỏi “Làm thế nào kiểm tra object tồn tại trong mảng hay không?” khi tìm kiếm bằng tiếng Việt trên Google thì câu trả lời nhận được dường như không rõ ràng và dễ gây nhầm lẫn. Đối với người đi làm rồi thì chuyện này không có gì quá khó khăn, chỉ cần đổi sang search bằng chút tiếng anh là ra được kết quả. Cơ mà với những bạn mới tập tành lập trình, cũng đang tập tành tiếng Anh thì hẳn có chút khó khăn (giống mình ngày xưa). Nên hôm nay mình ở đây để viết ra bài này.
functionhasObjectInArray(targetObject, sourceArray) { // chạy đến khi nào THỎA ĐIỀU KIỆN sẽ BREAK return sourceArray.some(i => { // kiểm tra số lượng properties bằng nhau không // không bằng tức khác nhau if (Object.keys(i).length !== Object.keys(targetObject).length) { returnfalse; }
// TODO so sánh deep object
// hàm every chạy để kiểm tra TẤT CẢ properties của i bằng với peroperties của targetObject // nhớ xài `===` để chắc chắn kiểu dữ liệu của các properties giống nhau returnObject.keys(i).every(k => i[k] === targetObject[k]); }); }
var object1 = { id: 3, name: 'cauliflower' }; var object2 = { id: 3, name: 'zucchini' };
Chú ý các hàm some() và every() là các method build sẵn trong ES6 để giúp duyệt mảng chất chơi người dơi hơn, về bản chất chúng đều là vòng lặp, nên các bạn có thể code bằng cách dùng for hoặc while gì đó nhá.
CHÚ Ý: bài toán sẽ phức tạp hơn nếu object kia lồng nhau, nghĩa là trong object lại có một object khác á. Này để bạn đọc tự khám phá nhé, simple nhất là dùng đệ quy.
Kiểm tra dựa vào 1 tiêu chí
Chú ý, việc so sánh tìm ra 2 object bằng nhau là khá khó khăn (so sánh tất cả các thuộc tính của object), nên phần dưới đây chúng ta sẽ đi tìm object trong mảng sẽ dựa vào một thuộc tính của object đó. Ví dụ student là một object, class là một mảng, muốn tìm một object (student) có trong mảng (class) hay không, thì dựa vào tên của học sinh (một thuộc tính), chứ tìm theo cách khác sẽ khá phức tạp.
Hàm này trả về index nó tìm được trong mảng, nếu tìm không thấy sẽ trả về -1. Vậy chỉ cần check index trả về có >= 0 là được rồi.
Dùng filter()
Hàm filter mặc định sẽ trả về mảng mới, mảng mới này chứa data hay không phụ thuộc vào callback truyền vào filter trả về true/false. i.name === 'chin' trả về true nghĩa là filter sẽ thêm i vào danh sách mảng sẽ trả về.
// ES6 var result = (partOfBody.filter(i => i.name === 'chin').length > 0); // false var result2 = (partOfBody.filter(i => i.name === 'knee').length > 0); // true
Ngoài ra bạn có thể làm với các method khác của Array, như reduce chẳng hạn. Cơ chế đằng sau đều là chạy vòng lặp để kiểm tra. Trong phạm vi các giải pháp mình nêu ra, tối ưu nhất mà code lại đẹp, đó là dùng some() hoặc findIndex().
functiondeepCompareObject(sourceObject, targetObject) { returnObject.keys(sourceObject).every(k => { // TODO need check đầy đủ các kiểu của object, như Date ... let bothIsObject = (sourceObject[k] && typeof sourceObject[k] === 'object' && targetObject[k] && typeof targetObject[k] === 'object');
if (bothIsObject) { returndeepCompareObject(sourceObject[k], targetObject[k]) }
var result1 = hasObjectInArray(object1, somethings); var result2 = hasObjectInArray(object2, somethings); var result3 = hasObjectInArray(object3, somethings); var result4 = hasObjectInArray(object4, somethings);