首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JavaScript 數組去重核心邏輯:o[v]=1 的精確含義

     編輯:程式設計綜合問答

代碼回顧

Array.prototype.unique = function() {
    var ret = [];      // 結果數組
    var o = {};        // 查找表(哈希表)
    var len = this.length;
    
    for (var i = 0; i < len; i++) {
        var v = this[i];        // 當前元素值
        if (!o[v]) {            // 若查找表中無此值
            o[v] = 1;           // 標記:已見過
            ret.push(v);        // 加入結果
        }
    }
    return ret;
};

o[v] = 1 的三層含義

1. 哈希表鍵值對結構

  • 鍵:數組元素值 v(如 1、2、"a")
  • 值:1(任意 truthy 值均可,true、"seen"、{} 皆可)
  • 作用:利用對象鍵的唯一性實現 O(1) 查重

2. 狀態標記機制

階段o 狀態條件判斷動作
初始{}--
遇到首個 1{"1": 1}!o[1] → truepush(1), o[1]=1
遇到第二個 1{"1": 1}!o[1] → false跳過
遇到 2{"1":1, "2":1}!o[2] → truepush(2), o[2]=1

3. JavaScript 隱式轉換利用

  • o[v] 返回 undefined(falsy)→ !undefined === true → 執行 if 內部
  • o[v] = 1 後,o[v] 返回 1(truthy)→ !1 === false → 跳過

為什麼值寫 1 而非 true?

  • 歷史習慣:早期 JS 引擎數字比布爾運算略快(現代引擎無差異)
  • 體積極小:1 比 true 少 3 字節
  • 語義足夠:只需 truthy/falsy 區分,無需具體語義值

現代優化寫法 (ES6+)


// Set 自動去重(最推薦,簡潔高效)
const unique = [...new Set(arr)];

// 或保留原型擴展風格
Array.prototype.unique = function() {
    return [...new Set(this)];
};

// Map 保持插入順序並支持對象去重
Array.prototype.uniqueBy = function(keyFn) {
    const map = new Map();
    return this.filter(item => {
        const key = keyFn(item);
        if (map.has(key)) return false;
        map.set(key, true);
        return true;
    });
};

性能對比 (10萬元素數組)

方法時間複雜度實測耗時備註
雙層循環 (indexOf)O(n²)~1200ms極慢,勿用
對象查找表 (o[v]=1)O(n)~8ms經典寫法,兼容舊環境
Set 構造器O(n)~3ms原生優化,首選
Map + filterO(n)~5ms支持複雜鍵提取

避坑指南

  • ❌ o[v] = 1 中 v 為對象/數組 → 鍵會被 toString() 為 "[object Object]" 導致誤判
  • ❌ NaN 去重失效:NaN !== NaN,但 Set 可正確處理
  • ❌ 原型污染:Array.prototype.unique 可能與庫衝突,模塊化項目建議用獨立函數

o[v] = 1 是利用對象鍵唯一性實現 O(1) 查重的經典模式,值 1 只是佔位符,核心是 「見過即標記,再見即跳過」 的狀態機邏輯。現代項目優先使用 Set。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved