js數組去重是前端面試中經常被問的題目,考察了面試者對js的掌握,解決問題的思路,以及是否具有專研精神。曾經一位前端界大神告訴我,解決問題的方式有很多種,解決問題時多問問自己還有沒有其他的方法,探求最優解決方案才能學到更多。
如果,這篇文章有幸被您閱讀,文中出現的錯誤,或者您有其他的解決方案請在評論區告訴我,謝謝。
方案一
/**
* 1.構建一個新數組
* 2.遍歷目標數組,依次取出每一個元素
* 3.將取出的元素與新數組里面的所有元素進行比較,
* 如果沒有出現 -> 該元素添加到新數組中,
* 如果出現 -> 處理下一個目標數組元素
* */
function distinct(arr) {
console.time(); //跟蹤方法的占用時長
var result = []; // 構建結果數組result
for (var i = 0, len = arr.length; i < len; i++) {
for (var j = 0, rlen = result.length; j <= rlen; j++) {
if (arr[i] === result[j]) {
break;
}
if (j == result.length) {
result.push(arr[i]);
}
}
}
console.timeEnd();
return result;
}
方案優點:
- 結果數組與目標數組的順序保持一致
- 思路簡單,兼容性好
方案缺點:
- 速度慢
方案二
/**
*1.目標數組排序
*2.遍歷目標數組,檢測數組中的第i 個元素與結果數組中最后一個元素是否相同,如果不同,則將該元素添加到結果數組中
* */
function distinct(arr) {
console.time();
var result = [];
arr = arr.sort();
for (var i = 0, len = arr.length; i < len; i++) {
if (arr[i] !== result[result.length - 1]) {
result.push(arr[i])
}
}
console.timeEnd();
return result;
}
方案優點:
- 方案中先排序,后遍歷,速度比方法一快
方案缺點:
- 方案中使用了數組排序sort,打亂了原有順序
Tips:數組排序
js中提供了數組排序方法sort,使用時需要注意以下幾點:
- 調用sort方法時改變了目標數組本身,非生成新數組
- sort方法默認按照字符順序進行排序,不過提供了回調方法,可以自定義排序規則
現有一數組arr:1,11,23,56,3,4,5,7,562,67
按字符排序
arr.sort() // 1, 11, 23, 3, 4, 5, 56, 562, 67, 7
按數字大小:正序
arr.sort((a,b) => a-b) // 1, 3, 4, 5, 7, 11, 23, 56, 67, 562
按數字大小:倒序
arr.sort((a,b) => b-a) // 562, 67, 56, 23, 11, 7, 5, 4, 3, 1
方案三
/**
* 利用ES6的 數據結構SET的無重復值特性
* Array.from 將類數組轉換成數組
* */
function distinct3(arr) {
console.time();
var result = Array.from(new Set(arr));
console.timeEnd();
return result;
}
方案優點:
- 代碼簡潔,執行速度快
方案缺點:
- ES6語法,使用時需要考慮兼容性問題
方案四
/**
* 利用對象屬性無重復的特點
* 遍歷目標數組,將值設置為對象屬性
* Object.keys 將對象的所有屬性提取成一個數組
* */
function distinct(arr) {
console.time();
var result = {};
for (var i = 0, len = arr.length; i < len; i++) {
result[arr[i]] = '';
}
result = Object.keys(result);
console.timeEnd();
return result;
}
方案優點:
- 速度快
方案缺點:
- 1 與 '1' 無法區分
- 結果數組中的值全部為字符串
- 占內存,相當於利用空間換時間
方案五
/**
* Array.filter 數組過濾函數,只保留符合條件的值
* indexOf 查找元素第一次出現的位置,所有第1次之后查找的元素位置都不符合條件
* */
function distinct(arr) {
console.time();
var result = arr.filter(function (elem, index, self) {
return self.indexOf(elem) === index;
});
console.timeEnd();
return result;
}
測試
隨機生成包含10000個數字的數組
function random() {
var a = [];
for (var i = 0; i < 10000; i++) {
a.push(Math.ceil(i * Math.random()))
}
return a;
}
現在執行上述去重方法,取5次測試結果的平均值:
方法一 | 方法二 | 方法三 | 方法四 | 方法五 | |
---|---|---|---|---|---|
第一次 | 91.281 | 7.921 | 4.36 | 2.038 | 68.856 |
第二次 | 104.492 | 7.519 | 2.267 | 1.328 | 70.555 |
第三次 | 105.937 | 8.874 | 1.804 | 1.680 | 73.020 |
第四次 | 100.524 | 5.287 | 2.602 | 1.573 | 85.129 |
第五次 | 106.612 | 8.990 | 1.615 | 1.963 | 79.115 |
平均 | 101.769 | 7.718 | 2.529 | 1.716 | 75.335 |
從執行速度來看,方法四 < 方法三 < 方法二 < 方法五 < 方法一
方法四最快,方法一最慢。但是五種方法各有優缺點,使用時要根據實際情況選擇適合的方案。
寫在最后
本篇文章旨在學習分享和記錄,並不是說數組去重只有這五種方法,如果文章中出現了錯誤,或者您有更好的解決方案,麻煩您在評論區告知我,謝謝。