Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> JavaScript

Cách so sánh hai mảng trong JavaScript

JavaScript so sánh mảng bằng === hoặc == kiểm tra tham chiếu (reference), không phải giá trị. [1,2] === [1,2] là false. Để so sánh nội dung (value), cần thuật toán tùy mục đích.

1. Tìm phần tử chung (Intersection) - Giống ví dụ gốc

const arr1 = [50, 60, 65, 90];
const arr2 = [25, 35, 50, 90];

// Cách đơn giản (O(n*m)) - Chỉ dùng mảng nhỏ
const common = [];
for (let i = 0; i < arr1.length; i++) {
    for (let j = 0; j < arr2.length; j++) {
        if (arr1[i] === arr2[j]) {
            common.push(arr1[i]);
        }
    }
}
console.log(common); // [50, 90]

2. Cách hiệu quả (O(n+m)) - Dùng Set (Khuyên dùng)

const arr1 = [50, 60, 65, 90];
const arr2 = [25, 35, 50, 90];

const set2 = new Set(arr2); // O(m)
const common = arr1.filter(x => set2.has(x)); // O(n)
console.log(common); // [50, 90] - Giữ thứ tự arr1, loại trùng lặp trong arr1 nếu có

3. Kiểm tra 2 mảng GIỐNG HỆT (Same elements, same order)

function arraysEqual(arr1, arr2) {
    if (arr1.length !== arr2.length) return false;
    for (let i = 0; i < arr1.length; i++) {
        if (arr1[i] !== arr2[i]) return false;
    }
    return true;
}

// Hoặc dùng JSON (chỉ cho kiểu dữ liệu đơn giản, không function, circular)
function arraysEqualJSON(arr1, arr2) {
    return JSON.stringify(arr1) === JSON.stringify(arr2);
}

console.log(arraysEqual([1,2,3], [1,2,3])); // true
console.log(arraysEqual([1,2,3], [1,3,2])); // false

4. Kiểm tra 2 mảng CÙNG PHẦN TỬ (Bỏ qua thứ tự)

function arraysEquiv(arr1, arr2) {
    if (arr1.length !== arr2.length) return false;
    const count = {};
    for (const x of arr1) count[x] = (count[x] || 0) + 1;
    for (const x of arr2) {
        if (!count[x]) return false;
        count[x]--;
    }
    return true;
}

console.log(arraysEquiv([1,2,3], [3,2,1])); // true
console.log(arraysEquiv([1,2,2], [2,1,1])); // false

5. So sánh mảng Object (Deep Compare)

const arr1 = [{id: 1}, {id: 2}];
const arr2 = [{id: 1}, {id: 2}];

// Cần so sánh sâu (deep equal) - dùng thư viện hoặc viết đệ quy
// Lodash: _.isEqual(arr1, arr2)
// Hoặc custom:
function deepEqual(a, b) {
    if (a === b) return true;
    if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
    if (Array.isArray(a) !== Array.isArray(b)) return false;
    if (a.length !== b.length) return false;
    for (let i = 0; i < a.length; i++) {
        if (!deepEqual(a[i], b[i])) return false;
    }
    return true;
}

So sánh hiệu năng & Ứng dụng

Mục đíchPhương phápĐộ phức tạpLưu ý
Tìm phần tử chungarr1.filter(x => new Set(arr2).has(x))O(n+m)Nhanh, giữ thứ tự arr1
Kiểm tra giống hệt (cùng thứ tự)Vòng lặp index hoặc JSON.stringifyO(n)JSON fail với function, Symbol, circular
Kiểm tra cùng phần tử (khác thứ tự)Frequency Counter (Object/Map)O(n+m)Chuẩn xác cho primitive
So sánh object/array lồng nhauLodash _.isEqual hoặc custom deepEqualO(n)Xử lý circular, Date, Regex, Map, Set

Ví dụ gốc (Tìm phần tử trùng) - Cải tiến

<html>
<body>
<script>
    var arr1 = [50, 60, 65, 90];
    var arr2 = [25, 35, 50, 90];
    
    // Tối ưu với Set
    var set2 = new Set(arr2);
    var matched = arr1.filter(x => set2.has(x));
    
    matched.forEach(val => document.write("Matched element: " + val + "<br>"));
    // Output: Matched element: 50, Matched element: 90
</script>
</body>
</html>

Tóm lại: JS không so sánh mảng bằng ===. Dùng Set + filter để tìm phần tử chung (nhanh, O(n+m)). Dùng vòng lặp index hoặc JSON.stringify (cẩn thận) để kiểm tra giống hệt. Dùng frequency counter cho cùng phần tử khác thứ tự. Object/Array lồng -> _.isEqual hoặc deepEqual custom.