JavaScript 數組唯一元素提取:利用 indexOf 和 lastIndexOf 精準去重

JavaScript 數組唯一元素提取:利用 indexOf 和 lastIndexOf 精準去重

本教程將詳細介紹如何利用 JavaScript 中數組的 indexOf() 和 lastIndexOf() 方法,結合 Filter() 函數,高效地從一個數組中篩選出所有只出現一次的唯一元素。文章通過代碼示例和逐步解析,幫助讀者深入理解該方法的原理和應用,實現精確的去重操作。

數組唯一元素提取的需求

在日常的 javascript 開發中,我們經常會遇到需要處理數組中重復數據的情況。有時,我們不僅需要移除所有重復項以獲得一個不包含任何重復值的數組(即去重),更具體的需求是,我們希望從數組中找出那些只出現過一次的元素,而將所有出現多次的元素全部剔除。例如,給定數組 [100, 123, 100, 122, 119, 203, 123, 76, 89],我們期望的輸出是 [122, 119, 203, 76, 89]。

核心原理:indexOf() 與 lastIndexOf() 的結合應用

解決上述問題的關鍵在于巧妙地利用 JavaScript 數組的兩個原生方法:Array.prototype.indexOf() 和 Array.prototype.lastIndexOf()。

  • indexOf(searchElement[, fromIndex]): 該方法返回在數組中可以找到一個給定元素的第一個(最小)索引,如果不存在,則返回 -1。它從數組的開頭(索引0)開始向后查找。
  • lastIndexOf(searchElement[, fromIndex]): 該方法返回在數組中可以找到一個給定元素的最后一個(最大)索引,如果不存在,則返回 -1。它從數組的末尾開始向前查找。

當一個元素在數組中只出現一次時,它的 indexOf() 和 lastIndexOf() 返回的索引值將是相同的。因為無論是從左側查找還是從右側查找,它都只會找到同一個位置的該元素。反之,如果一個元素在數組中出現多次,那么它的 indexOf()(第一次出現的索引)將與 lastIndexOf()(最后一次出現的索引)不同。

利用這一特性,我們可以結合 Array.prototype.filter() 方法來遍歷數組,并根據每個元素 indexOf(val) === lastIndexOf(val) 的條件進行篩選。

代碼實現

以下是使用 filter()、indexOf() 和 lastIndexOf() 方法實現該功能的 JavaScript 代碼示例:

立即學習Java免費學習筆記(深入)”;

const arr = [100, 123, 100, 122, 119, 203, 123, 76, 89];  /**  * 從數組中篩選出只出現一次的唯一元素  * @param {Array} data - 輸入數組  * @returns {Array} - 包含唯一元素的數組  */ const getUniqueElements = (data) => {     return data.filter((val) => data.indexOf(val) === data.lastIndexOf(val)); };  const result = getUniqueElements(arr); console.log(result); // 輸出: [122, 119, 203, 76, 89]

逐步解析示例

為了更深入地理解上述代碼的工作原理,我們以一個更簡單的數組 [1, 2, 3, 1, 2] 為例,逐步分析 filter() 方法在每個元素上的判斷過程。

假設我們有數組 arr = [1, 2, 3, 1, 2]。

  1. 處理第一個元素 1 (索引 0):

    • arr.indexOf(1) 返回 0 (從左側找到的第一個 1 的索引)。
    • arr.lastIndexOf(1) 返回 3 (從右側找到的最后一個 1 的索引)。
    • 0 === 3 為 false。因此,1 被過濾掉。
  2. 處理第二個元素 2 (索引 1):

    • arr.indexOf(2) 返回 1 (從左側找到的第一個 2 的索引)。
    • arr.lastIndexOf(2) 返回 4 (從右側找到的最后一個 2 的索引)。
    • 1 === 4 為 false。因此,2 被過濾掉。
  3. 處理第三個元素 3 (索引 2):

    • arr.indexOf(3) 返回 2 (從左側找到的第一個 3 的索引)。
    • arr.lastIndexOf(3) 返回 2 (從右側找到的最后一個 3 的索引)。
    • 2 === 2 為 true。因此,3 被保留。
  4. 處理第四個元素 1 (索引 3):

    • arr.indexOf(1) 返回 0 (從左側找到的第一個 1 的索引)。
    • arr.lastIndexOf(1) 返回 3 (從右側找到的最后一個 1 的索引)。
    • 0 === 3 為 false。因此,1 被過濾掉。
  5. 處理第五個元素 2 (索引 4):

    • arr.indexOf(2) 返回 1 (從左側找到的第一個 2 的索引)。
    • arr.lastIndexOf(2) 返回 4 (從右側找到的最后一個 2 的索引)。
    • 1 === 4 為 false。因此,2 被過濾掉。

經過所有元素的迭代,最終 filter() 方法將返回一個只包含 [3] 的新數組。這完美地符合了我們的預期,即只保留那些在原數組中只出現過一次的元素。

注意事項與總結

  • 性能考量: 盡管這種方法簡潔易懂,但在處理非常大的數組時,其性能可能不是最優的。因為對于數組中的每個元素,indexOf() 和 lastIndexOf() 都可能需要遍歷整個數組,導致時間復雜度接近 O(n^2)。對于百萬級別以上的數據量,可以考慮使用哈希表(mapObject)來統計元素出現次數,從而達到 O(n) 的時間復雜度。
  • 適用類型: 此方法適用于數組中包含基本數據類型(如數字、字符串、布爾值)的場景。對于包含對象或數組等引用類型的數組,indexOf() 和 lastIndexOf() 會進行嚴格相等(===)比較,這意味著它們只會查找引用地址完全相同的對象,而不會比較對象的內容。
  • 可讀性: 這種解決方案的可讀性非常好,通過 indexOf 和 lastIndexOf 的語義,能夠直觀地理解其篩選唯一元素的邏輯。

通過本文的講解,您應該已經掌握了如何利用 JavaScript 的 indexOf() 和 lastIndexOf() 方法結合 filter() 函數,高效且準確地從數組中提取出所有只出現一次的唯一元素。在實際開發中,根據具體的數據規模和性能要求,您可以選擇最適合的方案。

? 版權聲明
THE END
喜歡就支持一下吧
點贊13 分享