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

Lấy tất cả giá trị duy nhất (unique) trong mảng JavaScript

Lấy giá trị duy nhất từ mảng với Set

Cách hiện đại và hiệu quả nhất (ES6) là dùng Set - cấu trúc dữ liệu chỉ lưu giá trị duy nhất.

Ví dụ minh họa

<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Unique Array Values</title>
    <style>
        body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; }
        .result, .sample { font-size: 18px; font-weight: 500; color: rebeccapurple; font-family: monospace; }
        .result { color: red; }
        button { padding: 8px 16px; cursor: pointer; }
    </style>
</head>
<body>
    <h1>Lấy giá trị duy nhất trong mảng</h1>
    <div class="sample"></div>
    <div class="result"></div>
    <button class="btn-demo">LOẠI BỎ TRÙNG LẶP</button>
    <h3>Nhấn nút để xóa giá trị trùng lặp khỏi mảng</h3>

    <script>
        const resultEle = document.querySelector(".result");
        const sampleEle = document.querySelector(".sample");
        const btn = document.querySelector(".btn-demo");

        const arr = [2, 3, 4, 2, 3, 4, "A", "A", "B", "B"];
        sampleEle.textContent = "Mảng gốc: " + JSON.stringify(arr);

        btn.addEventListener("click", () => {
            // Cách 1: Set + Spread operator (ES6) - NGẮN GỌN NHẤT
            const unique = [...new Set(arr)];
            resultEle.textContent = "Unique (Set + spread): " + JSON.stringify(unique);
            
            // Cách 2: Array.from()
            resultEle.textContent += "\nArray.from: " + JSON.stringify(Array.from(new Set(arr)));
            
            // Cách 3: filter + indexOf (ES5, chậm O(n²))
            const uniqueOld = arr.filter((val, idx) => arr.indexOf(val) === idx);
            resultEle.textContent += "\nFilter indexOf: " + JSON.stringify(uniqueOld);
            
            // Cách 4: reduce (ES5)
            const uniqueReduce = arr.reduce((acc, val) => {
                if (!acc.includes(val)) acc.push(val);
                return acc;
            }, []);
            resultEle.textContent += "\nReduce: " + JSON.stringify(uniqueReduce);
        });
    </script>
</body>
</html>

So sánh hiệu suất

Phương pháp Độ phức tạp Hỗ trợ Khuyến nghị
[...new Set(arr)]O(n)ES6+✓ Tốt nhất
Array.from(new Set(arr))O(n)ES6+Tốt
filter + indexOfO(n²)ES5Tránh (mảng lớn)
reduce + includesO(n²)ES5Tránh (mảng lớn)
for loop + object mapO(n)ES5OK nếu không dùng Set

Unique cho mảng Object (theo property)

const users = [
    { id: 1, name: 'An' },
    { id: 2, name: 'Bình' },
    { id: 1, name: 'An (dup)' },
    { id: 3, name: 'Cường' }
];

// Unique theo id
const uniqueById = [...new Map(users.map(u => [u.id, u])).values()];
// [{id:1,name:'An'}, {id:2,name:'Bình'}, {id:3,name:'Cường'}]

// Unique theo nhiều property (composite key)
const uniqueByNameAge = [...new Map(
    users.map(u => [`${u.name}|${u.age}`, u])
).values()];

Unique giữ nguyên thứ tự (Set tự động giữ thứ tự insertion)

const arr = [3, 1, 2, 3, 1, 4];
[...new Set(arr)]; // [3, 1, 2, 4] - giữ thứ tự xuất hiện đầu tiên

Polyfill Set cho IE11

if (typeof Set === 'undefined') {
    // Simple polyfill hoặc dùng core-js
    // Hoặc dùng object map cho ES5:
    function unique(arr) {
        const seen = {};
        return arr.filter(item => {
            const key = typeof item + ':' + JSON.stringify(item);
            if (seen[key]) return false;
            seen[key] = true;
            return true;
        });
    }
}