欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關于JavaScript數(shù)組去重的一些理解匯總

 更新時間:2020年09月10日 10:49:11   作者:土豆愛麗絲兒  
這篇文章主要給大家介紹了關于JavaScript數(shù)組去重的一些理解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

做前端開發(fā)幾年,在項目中用到數(shù)組去重的機會倒不是很多,但是在面試的時候卻經(jīng)常被問到,個人理解,這道題真正考的是對JavaScript的基礎的掌握,因為有很多種方式可以做到。這次就根據(jù)這道題,將相關的知識理解透徹。

一、ES6中的new Set方式

先看看MDN上對Set的描述:

Set 對象允許你存儲任何類型的唯一值,無論是原始值或者是對象引用。
Set對象是值的集合,你可以按照插入的順序迭代它的元素。 Set中的元素只會出現(xiàn)一次,即 Set 中的元素是唯一的。

關鍵字:任何類型都可以存儲、存儲進來的值都是唯一的,這樣就可以做到先把數(shù)組中重復的數(shù)據(jù)去掉。

const list1 = [1, 2, 3, 7, 11, 56, 3, 2, 4, 5]
const list2 = new Set(list1)
console.log(list2) 

看一下返回的結果:

由結果可知,返回了一個可迭代的Set對象,此時還需要把Set對象轉(zhuǎn)為數(shù)組。此時可以用到
Array.from()。

**Array.from()** 方法從一個類似數(shù)組或可迭代對象創(chuàng)建一個新的,淺拷貝的數(shù)組實例.

剛好new Set()返回的就是一個可迭代的對象。

const list3 = Array.from(new Set([null, null, undefined, 12, undefined, 7, 2, 1, 22, 2, function a(){}, function a(){}, {}, {}]))

結果是返回了一個數(shù)組:

這種方式不考慮兼容性,且去不掉重復的function和{}

關于Array.from()的擴展

Array.from(arrayLike[, mapFn[, thisArg]])

arrayLike: 偽數(shù)組和可迭代對象

mapFn:每個元素會執(zhí)行這個回調(diào)方法

thisArg: 執(zhí)行回調(diào)函數(shù)時this的指向。

const list4 = Array.from('name', arg => arg + 12)
console.log(list4) // [ 'n12', 'a12', 'm12', 'e12' ]

偽數(shù)組對象(擁有一個 length 屬性和若干索引屬性的任意對象, 如string)

可迭代對象(可以獲取對象中的元素,如 Map和 Set 等)

二、set的另一種寫法

const list20 = [5, 3, 5, 5, 6, 37, 22, 22]
console.log([...new Set(list20)])

其實跟第一種差不多

三、嵌套的for循環(huán)

const list5 = [null, null, undefined, undefined, {}, {}, function q() {}, function q() {}, 34, 2, 1, 2]
for(let i = 0; i < list3.length; i++) {
  for (let j = i + 1; j < list3.length; j++) {
    if (list3[i] === list3[j]) {
      list3.splice(j, 1) // 將重復的數(shù)據(jù)刪掉一個
      j-- // 因為刪除掉了一個元素,就從這個元素的索引重新開始
    }
  }
}

這種方式用了splice(index, num)的方法,返回的結果也沒有把function和對象給去掉。我們能想到的最簡單的方式就是這種去重方式。

四、indexOf方式

const list6 = [null, null, undefined, undefined, NaN, NaN, false, 'false', function a(){}, function a() {}, {}, {}]
const list7 = []
for(let k = 0; k<list6.length; k++) {
  if (list7.indexOf(list6[k]) === -1) {
    list7.push(list6[k])
  }
}
console.log(list7, 'list7') 
// [null, undefined,NaN, NaN,false,'false',[Function: a], [Function: a],{},{}] list7

關于indexOf

Array構造函數(shù)和String構造函數(shù)的原型上都有這個方法

MDN上對他們的解釋分別是:

**indexOf()**方法返回在數(shù)組中可以找到一個給定元素的第一個索引,如果不存在,則返回-1。

arr.indexOf(searchElement[, fromIndex])

**indexOf()** 方法返回調(diào)用它的 String 對象中第一次出現(xiàn)的指定值的索引,從 fromIndex 處進行搜索。如果未找到該值,則返回 -1。

str.indexOf(searchValue [, fromIndex])

這么一看 就知道他倆用法一樣。

五、sort

先看看關于sort的解釋:

**sort()** 方法用原地算法對數(shù)組的元素進行排序,并返回數(shù)組。默認排序順序是在將元素轉(zhuǎn)換為字符串,然后比較它們的UTF-16代碼單元值序列時構建的
由于它取決于具體實現(xiàn),因此無法保證排序的時間和空間復雜性。

所以這種方式,在數(shù)組長的時候可能保證不了性能。用它去重的思路是什么呢?先用sort排序,然后前一個跟后一個比較,這樣相同的值永遠都是鄰關系。

const list8 = [null, null, undefined, undefined, NaN, NaN, false, 'false', function a(){}, function a() {}, {}, {}]
const list9 = list8.sort()
const list10 = [list9[0]]
for(let i = 1; i<list9.length; i++) {
  if (list9[i] !== list9[i-1]) {
    list10.push(list9[i])
  }
}

這一看就很容易理解。

六、includes

const list11 = [null, null, undefined, undefined, NaN, NaN, false, 'false', function a(){}, function a() {}, {}, {}]
const list12 = []
for (let i = 0; i<list11.length ; i++) {
  if (!list12.includes(list11[i])) {
    list12.push(list11[i])
  }
}

此結果沒有把function和{}去重,其他的都去重了。

includes也是Array構造函數(shù)和String構造函數(shù)上都有的方法。

七、filter和indexOf

// 數(shù)組去重方式6-filter和indexOf
const list13 = [1, 2, 3, 3, 5]
const list14 = list13.filter((item, index, arr) => {
  // 也就是在遍歷這個數(shù)組list13的時候,每次拿當前的元素跟此數(shù)組中這個元素第一次出現(xiàn)的位置相比,如果位置是一致的,就返回當前元素
  return list13.indexOf(item, 0) === index
})

八、遞歸

const list15 = [1, 2, 3, 4, 5, 7, 6, 4, 3]
const list16 = list15
const len = list16.length
list16.sort(function(a, b) { return a - b }) // 先排序
function loop(index) {
  if (index >= 1) {
    if (list16[index] === list16[index - 1]) {
      list16.splice(index, 1)
    }
  loop(index - 1)
  }
}
loop(len - 1)

關于sort排序

在排序的時候 我們可能忽略了一個問題,可能得到的并不是我們想要的結果,比如下面的例子:

const list17 = [22, 1, 2, 15, 3, 4, 3, 1, 11]
console.log(list17.sort()) // [1, 1, 11, 15, 2, 22, 3, 3, 4]

看看得到的結果,根本就不是按照從小到大排的。這是因為:默認排序順序是在將元素轉(zhuǎn)換為字符串,然后比較它們的UTF-16代碼單元值序列時構建的。
所以 要另找一種排序的方法,就是給sort傳入一個函數(shù)。

arr.sort([compareFunction])

參數(shù):

  • compareFunction: 可傳可不傳,傳的話用來指定按某種順序進行排列的函數(shù)。如果省略,元素按照轉(zhuǎn)換為的字符串的各個字符的Unicode位點進行排序。
  • compareFunction的參數(shù)1-firstEl: 用于比較的第一個元素
  • compareFunction的參數(shù)2-secondEl: 用于比較的第二個元素
  • 如果 compareFunction(a, b) 小于 0 ,那么 a 會被排列到 b 之前;
  • 如果 compareFunction(a, b) 等于 0 , a 和 b 的相對位置不變。備注: ECMAScript 標準并不保證這一行為,而且也不是所有瀏覽器都會遵守(例如 Mozilla 在 2003 年之前的版本);
  • 如果 compareFunction(a, b) 大于 0 , b 會被排列到 a 之前。
  • compareFunction(a, b) 必須總是對相同的輸入返回相同的比較結果,否則排序的結果將是不確定的。

返回值:

返回的是已經(jīng)原地排序的數(shù)組。

九、用Map數(shù)據(jù)結構排序

const list 18 = [2, 3, 33, 2, 5, 1, 3]
const map1 = new Map()
for(let i = 0; i<list18.length; i++) {
  if (map1.get(list18[i])) {
    map1.set(list18[i], true)
  } else {
    map1.set(list18[i], false)
    list19.push(list18[i])
  }
}

這個比較好理解, 就不多說了。

總結

到此這篇關于關于JavaScript數(shù)組去重的一些理解的文章就介紹到這了,更多相關JavaScript數(shù)組去重內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論