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

JavaScript 陣列去重並保持原始型別

     編輯:程式設計疑難解答

問題場景

開發者使用物件鍵值去重數字陣列 [2,1,2,10,2,3,4,1,85,321,3,4,65,10,24],但發現回傳結果型別與原陣列不一致(原為 number,去重後可能變為 string),詢問如何正確轉換。

原因分析

原代碼中 keys(obj) 函數遍歷物件屬性時,for...in 取得的鍵值為 字串。雖然使用 parseInt(attr) 轉換,但若物件鍵值包含非數字屬性(如原型鏈汙染),或轉換邏輯有誤,會導致結果異常。此外,toObject 以數值作為鍵時,JavaScript 會自動轉為字串,若後續處理不當即會型別錯位。

現代最佳實踐 (ES6+)

方法一:Set + 擴展運算子(最簡潔、效能佳)

const arr = [2,1,2,10,2,3,4,1,85,321,3,4,65,10,24];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [2, 1, 10, 3, 4, 85, 321, 65, 24] 型別保持 number

Set 自動去重並保持插入順序,擴展運算子還原為陣列,完整保留原始型別。

方法二:Array.from(new Set(arr))

const uniqueArr = Array.from(new Set(arr));

方法三:filter + indexOf(相容舊環境)

const uniqueArr = arr.filter((value, index, self) => self.indexOf(value) === index);

此法對大陣列效能較差(O(n²)),但不需 ES6 支援。

進階:任意型別去重(物件、陣列等)

若陣列元素為物件,Set 只能去除相同引用。需自訂比較邏輯:

// 依特定欄位去重
const uniqueBy = (arr, key) => [...new Map(arr.map(item => [item[key], item])).values()];

// 深度比較(效能較低)
const deepUnique = arr => arr.filter((item, i, self) => 
  i === self.findIndex(t => JSON.stringify(t) === JSON.stringify(item))
);

原代碼修正版(若必須用物件法)

function uniq(arr) {
  const seen = {};
  const result = [];
  for (const val of arr) {
    const key = typeof val + ':' + val; // 型別+值作鍵,區分 1 和 "1"
    if (!seen[key]) {
      seen[key] = true;
      result.push(val);
    }
  }
  return result;
}

總結

  • 現代專案首選 [...new Set(arr)],簡潔、高效、保持型別與順序。
  • 舊環境用 filter + indexOf 或 Map 輔助。
  • 避免手動 parseInt 物件鍵值,易出錯且效能低。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved