首頁  >  文章  >  web前端  >  JavaScript專題之二:陣列去重

JavaScript專題之二:陣列去重

coldplay.xixi
coldplay.xixi轉載
2021-03-03 10:23:451643瀏覽

JavaScript專題之二:陣列去重

目錄

  • 一、雙層迴圈(暴力方法)
  • 二、indexOf和includes
  • 三、排序去重
  • 四、filter
  • 五、鍵值對(key-value)
  • 六、ES6
  • 七、一些問題
  • 參考
  • 寫在最後

#(相關免費學習推薦:javascript影片教學

JavaScript專題之二:陣列去重

一、雙層循環

const unique = (arr)=>{
    for(let i = 0; i {
    var arr = [1, '1', '1', 1, 2, true, false, true, 3, 2, 2, 1];
    var newArr = [];
    for(let i = 0; i <p><strong>核心點:</strong></p>
  • 時間複雜度:O(n^2)
  • 上面的兩種方法都是兩次循環遍歷,處理方式略有不同
  • 上述實作方式確實不是最佳選擇,但它勝在相容性好啊~

二、indexOf和includes

2.1 indexOf簡化一層迴圈判斷

核心點:

  • 如果需要傳回原始數組,則可以在indexOf方法找到重複項時(不等於它首次出現的位置)時利用splice移除
  • indexOf:傳回在陣列中可以找到一個給定元素的第一個索引,如果不存在,則返回-1。
  • indexOf(ele, fromIndex)
    • ele:要尋找的元素
    • fromIndex:找出元素的起始位置,預設為0,允許負數,-2表示從倒數第二個元素開始找出
    • 傳回一個下標(number)

程式碼:

const unique = (arr) => {
    var res = [];
    for (let i = 0; i <h5>2.2 includes簡化一層循環判斷</h5><p> <strong>#核心點:</strong></p>
  • 具體的是要返回原始數組還是新數組大家可以自行組合~
  • includes:用來判斷陣列是否包含指定的值,根據情況,如果包含則傳回true,否則傳回false
  • includes(ele, fromIndex)  
    • ele:要尋找的元素
    • fromIndex:指定索引處開始尋找。預設為 0,如果為負值,從末尾開始往前跳 fromIndex 的絕對值個索引。 。
    • 傳回結果(bool)

##

const unique = (arr) => {
    var res = [];
    for (let i = 0; i 2.3 indexOf和includes對於目前場景的選擇<h5></h5>在這裡我們推薦使用includes來尋找元素:<p></p><p>傳回值可以直接作為if的條件語句,簡潔<strong></strong></p><pre class="brush:php;toolbar:false">if(res.indexOf(arr[i]) !== -1 ){ todo }// orif(res.includes(arr[i])){ todo }
##識別

NaN如果數組中有

NaN

,你又剛好需要判斷數組是否有存在NaN,這時你用indexOf是無法判斷的,你必須使用includes這個方法。 <pre class="brush:php;toolbar:false">var arr = [NaN, NaN];arr.indexOf(NaN); // -1arr.includes(NaN); // true</pre>

識別

undefined#如果陣列中有

undefined

值,includes#會認為空的值是undefined,而indexOf則不會。 <pre class="brush:php;toolbar:false">var arr = new Array(3);console.log(arr.indexOf(undefined)); //-1console.log(arr.includes(undefined)) //true</pre>

三、排序去重

核心點:

陣列排序後,相同的元素會相鄰,所以如果當前元素與它的相鄰元素不同,就存入到新數組中;
  • 相比於indexOf,只需要一層循環;
  • ##concat會拼接數組,並傳回新數組;
  • sort()排序是透過依照轉換為的
  • 字串的各個字元的Unicode位點
  • 進行排序。所以很難保證它的準確度;
  • 程式碼:

var arr = [1, 1, '1'];function unique(arr) {
    var res = [];
    var sortedArr = arr.concat().sort();
    var last;
    for (var i = 0; i <strong></strong>四、filter<p><strong># #核心點:</strong></p><p><strong>filter:方法建立一個新陣列, 其包含透過所提供</strong>函數實現的測試</p>的所有元素(傳回測試函數成立的元素) 
  • filter(callback, thisArg)
  • callback接受三個參數:element-目前正在處理的元素,index-當前元素索引,array-調用了filter的陣列本身thisArg:執行callback 時,用於this 的值。
      利用filter我們可以在程式碼層面簡化一下外層迴圈:

    #程式碼:
var arr = [1, 2, 1, 1, '1'];const unique = function (arr) {
    var res = arr.filter(function(item, index, arr){
        return arr.indexOf(item) === index;
    })
    return res;}console.log(unique(arr)); // [ 1, 2, '1' ]

結合排序的思路:

var arr = [1, 2, 1, 1, '1'];const unique = function (arr) {
    return arr.concat().sort().filter(function(item, index, arr){
        return !index || item !== arr[index - 1]
    })}console.log(unique(arr));

五、鍵值對(key-value)

#前面提到的幾種方式總結下來大致分為

非排序數組,兩次遍歷判斷(遍歷、查詢)

排序數組,相鄰元素比較
  1. 我們再提出一種方式,利用Object物件key-value的方式,來統計數組中元素出現的個數,初步判斷邏輯也有兩種
[1,1,1,2,2,3,'3']

舉例:

  1. 统计每个元素出现的次数,obj:{1: 3, 2: 2, 3: 3}, 返回这个objkey而不管他们的value
  2. 只元素首次出现,再次出现则证明他是重复元素
5.1 统计次数
var arr = [1, 2, 1, 1, '1', 3, 3];const unique = function(arr) {
    var obj = {};
    var res = [];
    arr.forEach(item => {
        if (!obj[item]) {
            obj[item] = true;
            res.push(item);
        }
    });
    return res;}console.log(unique(arr)); // [1, 2, 3]
5.2 结合filter
var arr = [1, 2, 1, 1, '1'];const unique = function(arr) {
    var obj = {};
    return arr.filter(function(item, index, arr){
        return obj.hasOwnProperty(item) ? false : (obj[item] = true)
    })}console.log(unique(arr)); // [1, 2]
5.3 key: value存在的问题

对象的属性是字符串类型的,即本身数字1字符串‘1’是不同的,但保存到对象中时会发生隐式类型转换,导致去重存在一定的隐患。

考虑到string和number的区别(typeof 1 === ‘number’, typeof ‘1’ === ‘string’),

所以我们可以使用 typeof item + item 拼成字符串作为 key 值来避免这个问题:

var arr = [1, 2, 1, 1, '1', 3, 3, '2'];const unique = function(arr) {
    var obj = {};
    var res = [];
    arr.forEach(item => {
        if (!obj[typeof item + item]) {
            obj[typeof item + item] = true;
            res.push(item);
        }
    });
    return res;}console.log(unique(arr)); // [ 1, 2, '1', 3, '2' ]

六、ES6

随着 ES6 的到来,去重的方法又有了进展,比如我们可以使用 Set 和 Map 数据结构。

6.1 Set

Set:它允许你存储任何类型的唯一值,无论是原始值或者是对象引用

代码:

var arr = [1, 2, 1, '1', '2'];const unique = function(arr) {
   return Array.from(new Set(arr));}console.log(unique(arr)); // [ 1, 2, '1', '2' ]

简化1:

function unique(array) {
    return [...new Set(array)];}

简化2:

var unique = (a) => [...new Set(a)]
6.2 Map

Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。

  • Map.prototype.has(key):返回一个布尔值,表示Map实例是否包含键对应的值。
  • Map.prototype.set(key, value):设置Map对象中键的值。返回该Map对象。
function unique (arr) {
    const newMap = new Map()
    return arr.filter((a) => !newMap.has(a) && newMap.set(a, 1));}

写到这里比较常规的数组去重方法就总结的差不多了,如果需要更强大的去重方法,我们需要对他们进行组合,而且因为场景的不同,我们所实现的方法并不一定能涵盖到

相关免费学习推荐:javascript(视频)

以上是JavaScript專題之二:陣列去重的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除