Rumah > hujung hadapan web > tutorial js > Nota kajian JavaScript: Kemahiran deduplication_javascript tatasusunan

Nota kajian JavaScript: Kemahiran deduplication_javascript tatasusunan

WBOY
Lepaskan: 2016-05-16 15:08:30
asal
1073 orang telah melayarinya

Bacaan yang disyorkan: Nota kajian JavaScript: Menambah, memadam, mengubah suai dan menyemak tatasusunan

Kaedah Jumlah Tatasusunan Nota Kajian JavaScript

Nota Kajian JavaScript Susunan Susunan Rawak

Dalam temu bual, penemuduga sering bertanyakan soalan tentang melaksanakan penyahduplikasian tatasusunan dalam JavaScript Baru-baru ini, saya kebetulan mempelajari tentang tatasusunan JavaScript dan mengambil peluang ini untuk menyusun beberapa kaedah untuk menyahduplikasi tatasusunan dalam JavaScript.

Kaedah deduplikasi tatasusunan berikut telah dikumpulkan dan disusun oleh saya sendiri Jika terdapat sebarang ralat, sila nyatakan ralat dalam teks.

Penyahduplikasi gelung berganda

Kaedah ini menggunakan dua gelung untuk traversal. Keseluruhan idea ialah:

Bina tatasusunan kosong untuk menyimpan tatasusunan nyahduplikasi

Gelung luar untuk merentasi tatasusunan asal, mengeluarkan elemen daripada tatasusunan setiap kali dan membandingkannya dengan tatasusunan hasil
Jika elemen yang dikeluarkan daripada tatasusunan asal adalah sama dengan elemen dalam tatasusunan hasil, keluarkan daripada gelung jika tidak, simpannya dalam tatasusunan hasil

Kod adalah seperti berikut:

Array.prototype.unique1 = function () {
// 构建一个新数组,存放结果
var newArray = [this[0]];
// for循环,每次从原数组中取出一个元素
// 用取出的元素循环与结果数组对比
for (var i = 1; i < this.length; i++) {
var repeat = false;
for (var j=0; j < newArray.length; j++) {
// 原数组取出的元素与结果数组元素相同
if(this[i] == newArray[j]) {
repeat = true;
break;
}
}
if(!repeat) {
// 如果结果数组中没有该元素,则存放到结果数组中
newArray.push(this[i]);
}
}
return newArray;
}
Salin selepas log masuk

Andaikan kita mempunyai tatasusunan seperti ini:

var arr = [1,2,3,4,'a','b',1,3,4,56,32,34,2,'b','c',5,'1',`2`];
arr.unique1(); // [1, 2, 3, 4, "a", "b", 56, 32, 34, "c", 5]
Salin selepas log masuk

Dikatakan kaedah ini memakan masa dan berintensif prestasi. Hanya lakukan ujian mudah (kaedah ujian ditulis dengan buruk):

function test () {
var arr = [];
for (var i = 0; i < 1000000; i++) {
arr.push(Math.round(Math.random(i) * 10000));
}
doTest(arr, 1);
}
function doTest(arr, n) {
var tStart = (new Date()).getTime();
var re = arr.unique1();
var tEnd = (new Date()).getTime();
console.log('双重循环去重方法使用时间是:' + (tEnd - tStart) + 'ms');
return re;
}
test();
Salin selepas log masuk

Jalankan kod di atas dalam pengawal Chrome dan uji masa yang diambil untuk penyahduaan gelung berganda: 11031ms.

Kaedah di atas boleh disimulasikan menggunakan kaedah forEach() dan kaedah indexOf():

function unique1() {
var newArray = [];
this.forEach(function (index) {
if (newArray.indexOf(index) == -1) {
newArray.push(index);
}
});
return newArray;
}
Salin selepas log masuk

Panggilan melalui unique1.apply(arr) atau unique1.call(arr). Walau bagaimanapun, kaedah ini jauh lebih cekap Kod ujian yang sama di atas mengambil masa 5423ms, yang hampir separuh daripada pantas.

Isih traversal untuk mengalih keluar pendua

Mula-mula gunakan kaedah sort() untuk mengisih tatasusunan asal Selepas mengisih, merentasi tatasusunan dan semak sama ada elemen ke-i dalam tatasusunan adalah sama dengan elemen terakhir dalam tatasusunan hasil. Jika berbeza, elemen diletakkan ke dalam tatasusunan yang terhasil.

Array.prototype.unique2 = function () {
// 原数组先排序
this.sort();
// 构建一个新数组存放结果
var newArray = [];
for (var i = 1; i < this.length; i++) {
// 检查原数中的第i个元素与结果中的最后一个元素是否相同
// 因为排序了,所以重复元素会在相邻位置
if(this[i] !== newArray[newArray.length - 1]) {
// 如果不同,将元素放到结果数组中
newArray.push(this[i]);
}
}
return newArray;
}
Salin selepas log masuk

Contohnya:

var arr = [1,2,3,4,'a','b',1,3,4,56,32,34,2,'b','c',5,'1','2'];
arr.unique2(); // ["1", 1, 2, "2", 3, 32, 34, 4, 5, 56, "a", "b", "c"]
Salin selepas log masuk

Kaedah ini mempunyai dua ciri:

Tatasusunan selepas penyahduplikasian akan diisih, terutamanya kerana nombor asal telah diisih sebelum penyahduplikasian

Dalam tatasusunan selepas penyahduaan, aksara angka yang sama dengan nombor tidak boleh dibezakan, seperti '1' dan 1

Menggunakan kaedah yang sama, masa ujian ialah: 1232ms.

Kaedah pasangan nilai kunci objek

Idea pelaksanaan kaedah deduplikasi ini ialah:

Buat objek JavaScript dan tatasusunan baharu

Gunakan gelung for untuk melintasi tatasusunan asal, mengeluarkan satu elemen setiap kali dan membandingkannya dengan kunci objek JavaScript

Jika ia tidak disertakan, tolak nilai elemen yang disimpan dalam objek ke dalam tatasusunan hasil, dan tetapkan nilai nama atribut yang disimpan dalam objek objek kepada 1

Kod adalah seperti berikut:

Array.prototype.unique3 = function () {
// 构建一个新数组存放结果
var newArray = [];
// 创建一个空对象
var object = {};
// for循环时,每次取出一个元素与对象进行对比
// 如果这个元素不重复,则将它存放到结果数中
// 同时把这个元素的内容作为对象的一个属性,并赋值为1,
// 存入到第2步建立的对象中
for (var i = 0; i < this.length; i++){
// 检测在object对象中是否包含遍历到的元素的值
if(!object[typeof(this[i]) + this[i]]) {
// 如果不包含,将存入对象的元素的值推入到结果数组中
newArray.push(this[i]);
// 如果不包含,存入object对象中该属性名的值设置为1
object[typeof(this[i]) + this[i]] = 1;
}
}
return newArray;
}
Salin selepas log masuk
Salin selepas log masuk

Jalankan contoh sebelumnya:

var arr = [1,2,3,4,'a','b',1,3,4,56,32,34,2,'b','c',5,'1','2'];
arr.unique3(); // [1, 2, 3, 4, "a", "b", 56, 32, 34, "c", 5, "1", "2"]
Salin selepas log masuk

Begitu juga, kunci yang berbeza mungkin disalah anggap sama; sebagai contoh: a[1], a["1"] . Masa yang diambil dengan kaedah ini: 621ms. Kaedah ini mengambil masa yang paling singkat, tetapi mengambil lebih banyak ingatan.

Selain kaedah di atas, terdapat beberapa kaedah lain seperti berikut:

// 方法四
Array.prototype.unique4 = function () {
// 构建一个新数组存放结果
var newArray = [];
// 遍历整个数组
for (var i = 0; i < this.length; i++) {
// 遍历是否有重复的值
for (j = i + 1; j < this.length; j++) {
// 如果有相同元素,自增i变量,跳出i的循环
if(this[i] === this[j]) {
j = ++i;
}
}
// 如果没有相同元素,将元素推入到结果数组中
newArray.push(this[i]);
}
return newArray;
}
Salin selepas log masuk

Keputusan ujian Chrome

var arr = [1,2,3,4,'a','b',1,3,4,56,32,34,2,'b','c',5,'1','2'];
arr.unique4(); // ["a", 1, 3, 4, 56, 32, 34, 2, "b", "c", 5, "1", "2"]
Salin selepas log masuk

Begitu juga, 1 dan '1' tidak dapat dibezakan.

// 方法五
Array.prototype.unique5 = function () {
// 构建一个新数组存放结果
var newArray = [];
// 遍历整个数组
for (var i = 0; i < this.length; i++) {
// 如果当前数组的第i值保存到临时数组,那么跳过
var index = this[i];
// 如果数组项不在结果数组中,将这个值推入结果数组中
if (newArray.indexOf(index) === -1) {
newArray.push(index);
}
}
return newArray;
}
Salin selepas log masuk

Keputusan ujian Chrome:

var arr = [1,2,3,4,'a','b',1,3,4,56,32,34,2,'b','c',5,'1','2'];
arr.unique6(); // [1, 2, 3, 4, "a", "b", 56, 32, 34, "c", 5, "1", "2"]
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Begitu juga, 1 dan '1' tidak dapat dibezakan. Masa yang dihabiskan: 14361ms.

// 方法六
Array.prototype.unique6 = function () {
return this.reduce(function (newArray, index) {
if(newArray.indexOf(index) < 0) {
newArray.push(index);
}
return newArray;
},[]);
}
Salin selepas log masuk

Keputusan ujian adalah seperti berikut:

var arr = [1,2,3,4,'a','b',1,3,4,56,32,34,2,'b','c',5,'1','2'];
arr.unique6(); // [1, 2, 3, 4, "a", "b", 56, 32, 34, "c", 5, "1", "2"]
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Masa diambil: 16490ms.

// 方法七
Array.prototype.unique7 = function(){
var newArray;
newArray = this.filter(function (ele,i,arr) {
return arr.indexOf(ele) === i;
});
return newArray;
}
Salin selepas log masuk

Keputusan ujian:

var arr = [1,2,3,4,'a','b',1,3,4,56,32,34,2,'b','c',5,'1','2'];
arr.unique6(); // [1, 2, 3, 4, "a", "b", 56, 32, 34, "c", 5, "1", "2"]
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Masa diambil: 13201ms.

Walaupun terdapat banyak kaedah, secara perbandingan, kaedah berikut adalah penyelesaian yang lebih baik:

Array.prototype.unique3 = function () {
// 构建一个新数组存放结果
var newArray = [];
// 创建一个空对象
var object = {};
// for循环时,每次取出一个元素与对象进行对比
// 如果这个元素不重复,则将它存放到结果数中
// 同时把这个元素的内容作为对象的一个属性,并赋值为1,
// 存入到第2步建立的对象中
for (var i = 0; i < this.length; i++){
// 检测在object对象中是否包含遍历到的元素的值
if(!object[typeof(this[i]) + this[i]]) {
// 如果不包含,将存入对象的元素的值推入到结果数组中
newArray.push(this[i]);
// 如果不包含,存入object对象中该属性名的值设置为1
object[typeof(this[i]) + this[i]] = 1;
}
}
return newArray;
}
Salin selepas log masuk
Salin selepas log masuk

Tetapi terdapat penyelesaian yang lebih ringkas dan dioptimumkan untuk penyahduplikasian dalam ES6, seperti:

// ES6
function unique (arr) {
const seen = new Map()
return arr.filter((a) => !seen.has(a) && seen.set(a, 1))
}
// or
function unique (arr) {
return Array.from(new Set(arr))
}
Salin selepas log masuk

Di atas ialah nota pembelajaran JavaScript yang diperkenalkan oleh editor untuk mengalih keluar pendua daripada tatasusunan saya harap ia akan membantu anda!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan