數組去重

很容易給出的方案是:數組

function arrayUnique(target) {
  var result = [target[0]];
  var temp = {};
  temp[target[0]] = true;
  for (var i = 1, len = target.length; i < len; i++) {
    if(temp[target[i]] === undefined) {
        result.push(target[i]);
        temp[target[i]] = true;
    }
  }
  return result;
}

arrayUnique([1, 2, 3, 4]); // [1, 2, 3, 4]
arrayUnique([1, 2, 3, 4, '1']); // [1, 2, 3, 4]

當給定數組變成[1, 2, 3, 4, '1']時,發現結果依然仍是 [1, 2, 3, 4],而實際上咱們期待的結果應該是[1, 2, 3, 4, '1']。
緣由很簡單,Object 會將屬性的 key 值都轉成 String 類型,好比,測試

var a = {1: 3, '3': 9}

Object.getOwnPropertyNames(a) // ["1", "3"]

上述例子中,兩個 key 值都被轉換成了字符串,再看一下下面一個例子:prototype

var a = {
    1: 3,
    '3': 9
}
Object.prototype.toString = function() {
    return 3;
}

console.log(a[{k: 1}]); // 9

當 key 值是一個object 的時候, 會先調用 toString 將該 object 轉成 字符串,再查找。
爲了解決這個問題,遍歷數組元素,與已保存的元素對比的時候還應該考慮元素的類型,以下:code

function arrayUnique(target) {
  var result = [target[0]];
  var temp = {};
  temp[target[0]] = {};
  temp[target[0]][(typeof target[0])] = 1;
  for (var i = 1, targetLen = target.length; i < targetLen; i++) {
    console.log(temp[target[i]], typeof target[i], temp[target[i]][typeof target[i]]);
    if(temp[target[i]] && temp[target[i]][typeof target[i]] === 1) {
        continue;
    }

    result.push(target[i]);
  
    if(typeof temp[target[i]] === 'undefined') {
        temp[target[i]] = {};
        temp[target[i]][typeof target[i]] = 1;
    } else {
        temp[target[i]][typeof target[i]] = 1;
    }
  }
  return result;
}

arrayUnique([1, '1', 1, 5, '5'); // [1, '1', 5, '5']

這樣就獲得了咱們想要的結果。有人會考慮temp對象自帶了一個__proto__和length屬性,可能在比較中會對結果形成影響。但在測試中,這兩個屬性只能經過點方法獲取,好比temp.__proto__, temp.length,而咱們實際比較中使用的是方括號,並不能獲取到這兩個屬性。因此貌似不用太擔憂,但當心爲上,仍是使用了Object.create(null),使對象儘量的純粹。對象

function arrayUnique(target) {
  var result = [target[0]];
  var temp = Object.create(null);
  temp[target[0]] = Object.create(null);
  temp[target[0]][(typeof target[0])] = 1;
  for (var i = 1, targetLen = target.length; i < targetLen; i++) {
    console.log(temp[target[i]], typeof target[i], temp[target[i]][typeof target[i]]);
    if(temp[target[i]] && temp[target[i]][typeof target[i]] === 1) {
        continue;
    }

    result.push(target[i]);
  
    if(typeof temp[target[i]] === 'undefined') {
        temp[target[i]] = Object.create(null);
        temp[target[i]][typeof target[i]] = 1;
    } else {
        temp[target[i]][typeof target[i]] = 1;
    }
  }
  return result;
}
相關文章
相關標籤/搜索