JS數組去重

不賣關子,直入主題es6

數組去重,最早想到的即是依次遍歷數組,在已遍歷的元素中查找是否存在當前數組元素,重點是用什麼存放已遍歷的數組,以及如何區分當前元素是否已存在算法

因爲下面會用到indexOf()的方法,它是ES5語法,低版本會存在兼容,先應添加對應的polyfillsegmentfault

Array.prototype.indexOf = Array.prototype.indexOf || function (searchElement, fromIndex) {
    var index = -1;
    fromIndex = fromIndex * 1 || 0;
    for (var k = 0, length = this.length; k < length; k++) {
        if (k >= fromIndex && this[k] === searchElement) {
            index = k;
            break;
        }
    }
    return index;
};

1.數組存放,indexOf()判斷數組

遍歷數組,創建新數組,利用indexOf判斷是否存在於新數組中,不存在則push到新數組,最後返回新數組函數

Array.prototype.unique = function() {
    var n = []; // 存放已遍歷的知足條件的元素
    for (var i = 0; i < this.length; i++) {
        // indexOf()判斷當前元素是否已存在
        if (n.indexOf(this[i]) == -1) n.push(this[i]);
    }
    return n;
}

下面是一個思想基本相同的變相版本性能

Array.prototype.unique = function() {
    // 建立一個新的臨時數組,而且把當前數組的第一元素存入到數組中
    var n = [this[0]]; 
    // 從第二項開始遍歷
    for (var i = 1; i < this.length; i++) 
    {
        // 若是當前數組的第i項在當前數組中第一次出現的位置不是i,那麼表示第i項是重複的,忽略掉,不然存入結果數組
        if (this.indexOf(this[i]) == i) n.push(this[i]);
    }
    return n;
}

JS引擎在實現indexOf()的時候會遍歷數組直到找到目標爲止,此函數會浪費掉不少時間。全部這兩種方式都不是最優的解決方式this

// es5簡化版
Array.prototype.unique = function() {
    return this.filter((v, i) => this.indexOf(v) === i)
}
// es6簡化版
Array.prototype.unique = function() {
    return Array.from(new Set(this));
}
// 或
Array.prototype.unique = function() {
    return [...new Set(this)];
}

2.對象存放,哈希算法(映射)判斷es5

Array.prototype.unique = function() {
    // n爲hash表,r爲臨時數組
    var n = {}, r = [];
    for (var i = 0; i < this.length; i++) {
        // 若是hash表中沒有當前項
        if (!n[this[i]]) {
            // 存入hash表
            n[this[i]] = true;
            // 把當前數組的當前項push到臨時數組裏面
            r.push(this[i]); 
        }
    }
    return r;
}

但從耗時的角度來說,這是最優的一種解決方式。可是從內存佔用角度來講,這並非最優的,由於多了一個hash表。這就是所謂的空間換時間prototype

3.先排序,後比較code

這種方式最大的優點就是排序後的比較次數變少,可是排序的過程也有性能消耗,應權衡使用

Array.prototype.unique = function() {
    this.sort();
    var re = [this[0]];
    for (var i = 1; i < this.length; i++) {
        if (this[i] !== re[re.length - 1]) {
            re.push(this[i]);
        }
    }
    return re;
}

這個方法的思路是先把數組排序,而後比較相鄰的兩個值。排序的時候用的JS原生的sort()方法,JS引擎內部應該是用的快速排序吧。這種方式比使用indexOf()的通常姿式要快,比使用hash表的最快姿式要慢,可是佔用內存要少

主要內容來自:數組去重的正確編寫姿式

相關文章
相關標籤/搜索