Tìm phần tử không lặp lại trong mảng JavaScript

Trong một dự án gần đây, một trong những nhiệm vụ của tôi là hiển thị hình ảnh từ API của dữ liệu sản phẩm. Mục tiêu là chọn các sản phẩm một cách ngẫu nhiên, không hiển thị trùng lặp. Tôi bắt đầu bằng cách sử dụng Toán. random() trên mảng API ban đầu, nhưng điều đó cho phép trùng lặp, vì vậy một số hình ảnh tự lặp lại trên trang

Giả sử chúng ta có một mảng dữ liệu API với năm phần tử mảng

['son môi', 'son bóng', 'bút kẻ mắt', 'má hồng', 'kem dưỡng ẩm']

và chúng tôi muốn tạo một mảng mới với ba phần tử mảng được chọn ngẫu nhiên, không lặp lại

Ví dụ: chúng tôi muốn điều này

['đỏ mặt', 'kem dưỡng ẩm', 'son môi'] vì các yếu tố không tự lặp lại

… nhưng chúng tôi KHÔNG muốn điều này

[‘lipgloss’, ‘blush’, ‘lipgloss’] bởi vì một yếu tố (son bóng) đang lặp lại chính nó

Điều quan trọng là đảm bảo rằng mỗi khi một yếu tố ngẫu nhiên được chọn, nó sẽ bị xóa khỏi nhóm dữ liệu có thể chọn

Đây là cách tôi giải quyết vấn đề đó

const apiArray = ['lipstick', 'lipgloss', 'eyeliner', 'blush', 'moisturizer']function genRandomElements(list) {
let arrayCopy = [...list];
let newArray = [];for(let i = 0; i < 3; i++) {
let randNum = Math.floor(Math.random()*arrayCopy.length);
let splicedItem = arrayCopy.splice(randNum, 1)[0]
newArray.push(splicedItem);
}
return newArray;
}
genRandomElements(apiArray);

Mảng API chứa dữ liệu mà từ đó chúng tôi muốn tạo một mảng mới gồm 3 phần tử ngẫu nhiên, không lặp lại. Chúng tôi khai báo nó với biến apiArray

Sau đó, chúng tôi khai báo hàm genRandomElements với danh sách là tham số. Trong trường hợp của chúng tôi, chúng tôi sẽ chuyển apiArray làm đối số để khi chúng tôi gọi hàm trên apiArray của mình, nó sẽ trông như thế này

genRandomElements(apiArray);

Chúng tôi bắt đầu chức năng này bằng cách tạo hai mảng mới. Đầu tiên là một bản sao của mảng API, được gọi là arrayCopy, được tạo bằng cách sử dụng toán tử trải rộng trên tham số được truyền vào, apiArray (xem […list]). Lý do chúng tôi tạo một bản sao là vì chúng tôi sẽ sử dụng splice(), đây là một phương pháp phá hủy, để chọn các phần tử ngẫu nhiên từ mảngCopy và chúng tôi không muốn thực hiện các thay đổi đối với mảng API thực tế

Mảng mới được tạo thứ hai là một mảng trống và được gán biến newArray. Đây là mảng mà chúng ta sẽ chèn các phần tử được chọn ngẫu nhiên, không lặp lại từ arrayCopy vào

Chúng tôi sử dụng vòng lặp for để yêu cầu công cụ Javascript lặp qua arrayCopy ba lần. Mỗi lần nó đi qua vòng lặp, nó sẽ xóa một phần tử mảng được chọn ngẫu nhiên khỏi arrayCopy và 'đẩy' phần tử mảng đó vào newArray. Sau lần lặp đầu tiên, trong mỗi lần lặp tiếp theo, (các) mục đã (đã) được chọn trong (các) lần lặp trước đó không còn bên trong ArrayCopy, vì vậy chúng không thể được chọn lại. Sau khi lặp qua ba lần, mảng newArray của chúng ta sẽ được điền với 3 phần tử được chọn ngẫu nhiên từ mảngCopy

for(let i = 0; i < 3; i++) {
let randNum = Math.floor(Math.random()*arrayCopy.length);
let splicedItem = arrayCopy.splice(randNum, 1)[0]
newArray.push(splicedItem);
}

Vòng lặp for sẽ bắt đầu từ i=0 và sẽ tăng dần cho đến khi i không còn nhỏ hơn 3. Nói cách khác, nó sẽ chạy mã trong dấu ngoặc nhọn {} ba lần (đếm i = 0, i = 1 và i = 2)

Bên trong dấu ngoặc nhọn, đầu tiên chúng ta gán Toán. tầng (Toán. ngẫu nhiên()*mảngCopy. chiều dài cho biến randNum

Trong ví dụ của chúng tôi, randNum sẽ là một số nguyên ngẫu nhiên trong khoảng từ 0 đến 4, bởi vì

môn Toán. random() tạo ra một số ngẫu nhiên giữa 0 và 1, bao gồm 0, nhưng không bao gồm 1. Tức là 0 ≤ Toán. ngẫu nhiên() < 1. Nó có thể là 0. 8988672771925821 chẳng hạn

mảngSao chép. chiều dài là chiều dài của mảngCopy (là bản sao của mảng API). Trong ví dụ của chúng tôi, nó có độ dài là 5 (có năm phần tử trong đó)

Khi chúng ta nhân Toán. ngẫu nhiên () bởi mảngCopy. độ dài, nó dẫn đến một số từ 0 đến độ dài của mảng. Vì vậy, tiếp tục ví dụ của chúng tôi, nó có thể là. 0. 8988672771925821*5 = 4. 49433638596291

Vì mục đích của chúng tôi là chọn một phần tử ngẫu nhiên từ arrayCopy và chúng tôi biết rằng các phần tử mảng được lập chỉ mục dưới dạng số nguyên bắt đầu từ 0 (chỉ mục 0 là phần tử đầu tiên, chỉ mục 1 là phần tử thứ hai, chỉ số n là (n+1)th

Bằng cách áp dụng Toán học. floor(), chúng tôi đang buộc số ngẫu nhiên phải là một số nguyên trong khoảng từ 0 đến 4. Lưu ý rằng mảng của chúng tôi có 5 phần tử, được lập chỉ mục từ 0 đến 4. Tiếp tục với ví dụ trên, Toán. tầng (4. 49433638596291) sẽ trả về 4

Vì vậy, randNum là một số nguyên được tạo ngẫu nhiên trong phạm vi số chỉ mục của mảng mà từ đó chúng tôi muốn lấy các phần tử, đây chính là thứ chúng tôi muốn

Splice là một phương thức phá hoại làm thay đổi nội dung của một mảng bằng cách loại bỏ các phần tử hiện có, trả về một mảng mới chứa các phần tử đã bị loại bỏ khỏi mảng mà splice() đã được áp dụng cho

Chúng tôi sử dụng randNum làm tham số bắt đầu cho mối nối trên mảngCopy. Sau đó, chúng tôi sử dụng 1 làm tham số xóaCount

mảngSao chép. mối nối (randNum, 1)

Trước mối nối, arrayCopy trông như thế này

['son môi', 'son bóng', 'bút kẻ mắt', 'má hồng', 'kem dưỡng ẩm']

Nếu chúng ta cắm vào ví dụ của mình, trong đó randNum là 4, chúng ta có arrayCopy. mối nối (4, 1), loại bỏ phần tử ở chỉ mục 4 khỏi mảngCopy và tạo một mảng riêng với phần tử đã loại bỏ

Trong arrayCopy, chỉ số 4 là ‘kem dưỡng ẩm’

Vì vậy,

mảngCopy sau mối nối bây giờ trông như thế này

['son môi', 'son bóng', 'bút kẻ mắt', 'má hồng']

mảngSao chép. mối nối(4, 1) = [‘kem dưỡng ẩm’]

mảngSao chép. splice(randNum, 1) tự nó là một mảng chứa phần tử, trước mối nối, được lập chỉ mục tại randNum (4 trong ví dụ trên) trong arrayCopy

Đó là phần tử mà chúng tôi muốn đặt vào newArray

Để truy cập phần tử chứ không phải toàn bộ mảng, chúng ta đặt dấu ngoặc vuông có số 0 bên trong ([0]) vào cuối mảng mới được tạo do nối mảngCopy. mảngSao chép. mối nối(randNum, 1)[0]

Một lần nữa với ví dụ đang chạy, hãy xem điều đó

mảngSao chép. mối nối(4, 1) = [‘kem dưỡng ẩm’]

Vì vậy,

mảngSao chép. mối nối(4, 1)[0] = 'kem dưỡng ẩm'

Bằng cách thêm [0], chúng tôi xác định rằng chúng tôi muốn phần tử ở chỉ mục 0

mảngSao chép. splice(randNum, 1)[0] chính xác là những gì chúng ta muốn đặt vào newArray. Chúng tôi gán nó cho biến splicedItem

Sau đó chúng ta sử dụng phương thức push() để chèn splicedItem vào newArray

Kinh ngạc. newArray hiện chứa một phần tử ngẫu nhiên từ arrayCopy

Sau đó, chúng tôi đóng vòng lặp của chúng tôi. Điều đó đánh dấu một vòng lặp thông qua. Sau đó, vòng lặp for sẽ tăng thêm 1 và lặp lại

Lần sau chạy qua sẽ không chọn được phần tử đã chọn trước đó. Đó là bởi vì bằng cách nối, chúng tôi đã xóa phần tử khỏi arrayCopy

Trong trường hợp của chúng tôi, vì chúng tôi đặt vòng lặp kết thúc tại i < 3, nên nó sẽ lặp lại hai lần nữa

Sau vòng lặp cuối cùng, nó rời khỏi khối mã và kết thúc chức năng bằng cách trả về mảng mới, hiện chứa 3 phần tử được chọn ngẫu nhiên từ mảng arrayCopy

Làm cách nào để tìm phần tử không lặp lại trong mảng trong JavaScript?

Lấy một mảng làm mảng kết quả là duy nhất. Kiểm tra i và j và nếu bằng nhau thì tiếp tục vòng lặp (bên trong). Kiểm tra giá trị tại i và j và thoát khỏi vòng lặp (bên trong), vì tìm thấy giá trị trùng lặp. Thực hiện kiểm tra ở cuối vòng lặp bên trong và kiểm tra chỉ số j với độ dài của mảng l và nếu bằng nhau, hãy đẩy giá trị thành duy nhất

Làm cách nào để tìm các phần tử lặp lại trong một mảng JavaScript?

Sử dụng các Phương thức filter() và indexOf() .

Làm cách nào để nhận các giá trị duy nhất trong JavaScript mảng?

Sử dụng EcmaScript 2016 bạn chỉ cần làm như thế này. var arr = ["a", "a", "b"]; . from(new Set(arr)); . Sets are always unique, and using Array.

Làm cách nào để loại bỏ các bản sao trong mảng JavaScript?

Phương thức Javascript filter(). Phương thức filter() tạo một mảng mới gồm các phần tử vượt qua điều kiện mà chúng ta cung cấp. Nó sẽ chỉ bao gồm những phần tử mà giá trị true được trả về. Chúng ta có thể loại bỏ các giá trị trùng lặp khỏi mảng bằng cách điều chỉnh điều kiện .