Xóa mục trùng lặp trong mảng javascript

Làm thế nào chúng ta có thể viết mã khi chúng ta muốn lấy các giá trị duy nhất từ ​​một mảng?

Liên kết được Tài trợ

Mục lục

  1. Phân biệt một mảng các giá trị nguyên thủy
    1. So sánh từng giá trị một
    2. Sử dụng mảng. nguyên mẫu. giảm
    3. Sử dụng mảng. nguyên mẫu. người làm hồ sơ
    4. Sử dụng bản đồ
    5. Sử dụng đối tượng Đặt
  2. Phân biệt một mảng đối tượng khóa-giá trị
    1. sử dụng lodash. isEqual
  3. So sánh hiệu suất
    1. Độ dài mảng 10
    2. Độ dài mảng 10 vòng lặp 10000 đến 200000
    3. Độ dài mảng 100
    4. Độ dài mảng 1000
  4. Sự kết luận

Phân biệt một mảng các giá trị nguyên thủy

Các mảng mà chúng ta sẽ sử dụng như sau. Mảng số và chuỗi. Chúng ta cần xử lý một mảng đối tượng theo cách khác, vì vậy hãy bắt đầu với một mảng đơn giản

const primitiveNumbers = [1, 2, 3, 2, 4, 5, 6, 3, 1];
// unique values -> [ 1, 2, 3, 4, 5, 6 ]
const primitiveStrings = [
    "aaa", // duplicated 1
    "bbb",
    "ddd", // duplicated 2
    "aaa", // duplicated 1
    "eee",
    "ccc",
    "ddd", // duplicated 2
];
// unique values -> [ 'aaa', 'bbb', 'ddd', 'eee', 'ccc' ]

Chúng ta cần thực hiện một số chức năng để xem các kết quả đó có giống nhau không. Tôi chuẩn bị chức năng chung để làm cho nó dễ dàng

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);

Tất cả các hàm được định nghĩa là loại

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
4 yêu cầu biến
type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
5. Chúng ta có thể chỉ định bất cứ thứ gì miễn là nó là một mảng nhưng tôi sẽ chỉ sử dụng số/chuỗi/đối tượng trong bài đăng này.
______16 chức năng đo lường thời gian cần thiết để hoàn thành công việc của chức năng.
type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
7 chức năng lưu trữ mà tôi sẽ trình bày trong bài đăng này.

So sánh từng giá trị một

Ý tưởng đầu tiên là lặp mảng và kiểm tra xem mục đó đã được hiển thị hay chưa. Thêm giá trị nếu nó chưa có trong biến

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
8

function uniqByObject(array: T[]) {
    const result: T[] = [];
    for (const item of array) {
        if (!result.includes(item)) {
            result.push(item);
        }
    }
    return result;
}

Nếu bạn thích forEach, bạn có thể viết nó như thế này bên dưới

________số 8

Sử dụng mảng. nguyên mẫu. giảm

Có nhiều cách khác nếu bạn không muốn xác định người trung gian lưu trữ kết quả

function uniqByReduce(array: T[]): T[] {
    return array.reduce((acc: T[], cur: T) => {
        if (!acc.includes(cur)) {
            acc.push(cur);
        }
        return acc;
    }, [])
}

Đối số đầu tiên

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
9 của lệnh gọi lại hàm
function uniqByObject(array: T[]) {
    const result: T[] = [];
    for (const item of array) {
        if (!result.includes(item)) {
            result.push(item);
        }
    }
    return result;
}
0 là một bộ tích lũy sẽ là giá trị trả về. Arg cur thứ hai là giá trị hiện tại. Những gì nó làm về cơ bản giống như các ví dụ trước

Sử dụng mảng. nguyên mẫu. người làm hồ sơ

Nó có thể được viết bằng một dòng nếu sử dụng chức năng lọc

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
2

Hành vi của

function uniqByObject(array: T[]) {
    const result: T[] = [];
    for (const item of array) {
        if (!result.includes(item)) {
            result.push(item);
        }
    }
    return result;
}
1 đang tuân theo

Phương thức indexOf() trả về chỉ mục đầu tiên mà tại đó có thể tìm thấy phần tử đã cho trong mảng hoặc -1 nếu không có phần tử đó

Bảng này cho thấy các mối quan hệ

indexvalueindexOfresult010true121true232true321false444true555true666true732false810false

Vì hàm

function uniqByObject(array: T[]) {
    const result: T[] = [];
    for (const item of array) {
        if (!result.includes(item)) {
            result.push(item);
        }
    }
    return result;
}
1 trả về chỉ số đầu tiên nên kết quả của
function uniqByObject(array: T[]) {
    const result: T[] = [];
    for (const item of array) {
        if (!result.includes(item)) {
            result.push(item);
        }
    }
    return result;
}
1 khác với chỉ số hiện tại của mảng

Sử dụng bản đồ

Bản đồ cung cấp đối tượng khóa-giá trị. Nếu nó nhận được cùng một tên khóa, nó sẽ cập nhật giá trị. Điều đó có nghĩa là chúng ta không phải kiểm tra các giá trị trong đó nếu sử dụng giá trị làm khóa

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
6

function uniqByObject(array: T[]) {
    const result: T[] = [];
    for (const item of array) {
        if (!result.includes(item)) {
            result.push(item);
        }
    }
    return result;
}
4 trả về loại
function uniqByObject(array: T[]) {
    const result: T[] = [];
    for (const item of array) {
        if (!result.includes(item)) {
            result.push(item);
        }
    }
    return result;
}
5 nhưng không phải mảng. Nó nên được chuyển đổi thành kiểu Array. Đó là lý do tại sao
function uniqByObject(array: T[]) {
    const result: T[] = [];
    for (const item of array) {
        if (!result.includes(item)) {
            result.push(item);
        }
    }
    return result;
}
6 được sử dụng ở đây

Sử dụng đối tượng Đặt

Tôi nghĩ đó là cách dễ nhất để làm điều đó. Những gì chúng ta phải làm chỉ là đặt mảng vào hàm tạo. Đặt đối tượng lưu trữ các giá trị duy nhất. Nó loại bỏ các bản sao

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
0

Thật không may, nó không thể được sử dụng cho một đối tượng vì nó đề cập đến một tham chiếu chứ không phải các giá trị trong đối tượng

Liên kết được Tài trợ

Phân biệt một mảng đối tượng khóa-giá trị

Các ví dụ mà tôi đã trình bày ở trên không thể được sử dụng cho một đối tượng. Một đối tượng không đơn giản như một giá trị nguyên thủy bởi vì nó đề cập đến một tham chiếu. Hai đối tượng sau có cùng giá trị nhưng kết quả là sai

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
1

Nếu cùng một tham chiếu được gán cho một biến khác, kết quả sẽ trở thành true

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
2

Các đối tượng được xác định ở đâu đó trong không gian địa chỉ. Giá trị tham chiếu của đối tượng là địa chỉ.

function uniqByObject(array: T[]) {
    const result: T[] = [];
    for (const item of array) {
        if (!result.includes(item)) {
            result.push(item);
        }
    }
    return result;
}
7 và
function uniqByObject(array: T[]) {
    const result: T[] = [];
    for (const item of array) {
        if (!result.includes(item)) {
            result.push(item);
        }
    }
    return result;
}
8 tương ứng được lưu trữ ở các địa chỉ khác nhau
function uniqByObject(array: T[]) {
    const result: T[] = [];
    for (const item of array) {
        if (!result.includes(item)) {
            result.push(item);
        }
    }
    return result;
}
9 trở thành sai

Để so sánh các đối tượng, chúng ta cần kiểm tra từng giá trị một. Chúng ta sẽ sử dụng đối tượng sau

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
0

sử dụng lodash. isEqual

Cách cho đối tượng về cơ bản giống như cách cho các giá trị nguyên thủy. Lặp lại mảng và kiểm tra từng giá trị một. Sự khác biệt là sử dụng

function uniqByForEach(array: T[]) {
    const result: T[] = [];
    array.forEach((item) => {
        if (!result.includes(item)) {
            result.push(item);
        }
    })
    return result;
}
0 để so sánh tất cả các giá trị nguyên thủy trong đối tượng

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
1

Chức năng này cũng có thể được sử dụng cho các giá trị nguyên thủy

So sánh hiệu suất

Hãy so sánh hiệu suất của các chức năng. Tôi đã sử dụng Nút. js phiên bản 14. 13. 0 cho thí nghiệm. Đây là mã cho nó

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
2

Phạm vi giá trị được đặt thành 0 – 9. Cùng một mảng được sử dụng trong vòng lặp cho tất cả các hàm để so sánh hiệu suất một cách chính xác. Nếu bạn muốn tự mình thử, bạn có thể sao chép kho lưu trữ của tôi hoặc chỉ cần sao chép và dán mã. Bạn có thể thay đổi phạm vi nếu bạn thay đổi giá trị đối số thứ hai của hàm

function uniqByForEach(array: T[]) {
    const result: T[] = [];
    array.forEach((item) => {
        if (!result.includes(item)) {
            result.push(item);
        }
    })
    return result;
}
1

BlogPost/khác biệt. ts tại master · yuto-yuto/BlogPost

Đóng góp cho sự phát triển của yuto-yuto/BlogPost bằng cách tạo một tài khoản trên GitHub

Xóa mục trùng lặp trong mảng javascript

github. com

Tôi đã thử đoạn mã sau để làm cho nó nhanh hơn

type UniqFunc = (array: T[]) => T[];
function test(array: T[], funcs: UniqFunc[]) {
    for (const func of funcs) {
        const start = performance.now();
        const result = func(array);
        const elapsedTime = performance.now() - start;
        console.log(`${func.name}, time: ${Math.round(elapsedTime)}`);
        console.log(result);
    }
}

const funcsForPrimitive = [
    uniqByForOf,
    uniqByForEach,
    uniqByReduce,
    uniqByFilter,
    uniqBySetWithArrayFrom,
    uniqBySetWithSpread,
];
test(primitiveNumbers, funcsForPrimitive);
test(primitiveStrings, funcsForPrimitive);
3

Tuy nhiên, nó đã không cải thiện nó vì lời hứa hoạt động trên một luồng duy nhất. Ví dụ, nó có thể cải thiện hiệu suất cho công việc liên quan đến I/O nhưng không phải cho công việc sử dụng nhiều CPU. Để cải thiện hiệu suất cho công việc sử dụng nhiều CPU, chúng tôi cần một luồng khác. Chúng ta có thể làm cho nó nhanh hơn bằng worker thread nhưng tôi không làm ở đây

Làm cách nào để xóa các mục trùng lặp trong một mảng?

Chúng ta có thể loại bỏ phần tử trùng trong mảng bằng 2 cách. dùng mảng tạm thời hoặc dùng chỉ mục riêng . Để loại bỏ phần tử trùng lặp khỏi mảng, mảng phải được sắp xếp theo thứ tự. Nếu mảng không được sắp xếp, bạn có thể sắp xếp nó bằng cách gọi Arrays. phương thức sắp xếp (mảng).

Có bao nhiêu cách chúng ta có thể loại bỏ các bản sao khỏi mảng trong JavaScript?

Nhiều phương pháp loại bỏ các bản trùng lặp khỏi một mảng .
1) Sử dụng phương thức filter()
2) Sử dụng phương thức set()
3) Sử dụng for mỗi phương pháp
4) Sử dụng phương thức reduce()
5) Theo tên tài sản
6) Bằng cách sử dụng JS gạch dưới

Bộ JavaScript có loại bỏ trùng lặp không?

Ví dụ 2. Sử dụng Bộ . Set là tập hợp các giá trị duy nhất. Tại đây, Mảng được chuyển đổi thành Tập hợp và tất cả các phần tử trùng lặp sẽ tự động bị xóa. Set is used to remove duplicate items from an array. A Set is a collection of unique values. Here, The array is converted to Set and all the duplicate elements are automatically removed.