偶然看到某大廠的一個面試題,
原題大概是這樣的:用一行代碼實現(xiàn)數(shù)組去重饿凛。
比如:var arr1 = [1,2,4,2,3,5,1,3];
數(shù)組去重有多種實現(xiàn)方式狞玛,但用一行代碼能搞定?
是的笤喳,查閱資料真有答案为居!
// 方法一:
var arr1 = [1,2,4,2,3,5,1,3];
var arr2 = [...new Set(arr1)];
console.log(arr2);// [1, 2, 4, 3, 5]
// 方法二:
var arr1 = [1,2,4,2,3,5,1,3];
var arr2 = Array.from(new Set(arr1));
console.log(arr2);// [1, 2, 4, 3, 5]
第一行是題目,第三行是輸出驗證結(jié)果杀狡,確實第二行就搞定了數(shù)組去重蒙畴!
看到 […new Set(arr1)] 的時候,第一反應(yīng)是:還有這種操作,感覺好高大上有木有膳凝!
先來搞明白這三個點是什么鬼東西碑隆。
es6 擴展運算符(…)
擴展運算符用三個點號表示,其功能是把數(shù)組或類數(shù)組對象展開成一系列用逗號隔開的參數(shù)序列蹬音。
console.log(...[1, 2, 3]);// 1 2 3
console.log(1, ...[2, 3, 4], 5);// 1 2 3 4 5
感覺挺好用上煤,再看看其他用法。
var arr1 = [1,2];
var arr2 = [3,4,5];
function addItems(arr, ...items) {
arr.push(...items);
};
addItems(arr1,...arr2);
console.log(arr1);// [1, 2, 3, 4, 5]
arr.push(…items) 和 addItems(arr1,…arr2) 這兩行是函數(shù)的調(diào)用著淆,都使用了擴展運算符將數(shù)組變?yōu)閰?shù)序列劫狠。
注意這行:function addItems(arr, …items) { 這里的三個點并不是擴展運算符,而是 rest運算符永部。
es6 rest運算符(…)
rest運算符也是三個點独泞,其功能與擴展運算符恰好相反,把逗號隔開的參數(shù)序列組合成一個數(shù)組苔埋。
var arr = [1,2,3];
function fn(...args) {// rest運算符 組合數(shù)組
console.log(args);// [1, 2, 3]
};
fn(...arr);// 擴展運算符 展開數(shù)組
console.log(...arr);// 1 2 3
當然了懦砂,這三個點還有很多很多妙用,在此暫不深入研究组橄。
那么 new Set() 又是什么東東荞膘?
es6 提供了兩種新的數(shù)據(jù)結(jié)構(gòu) Set 和 Map。
Set 是一個構(gòu)造函數(shù)玉工,用來生成 Set 數(shù)據(jù)結(jié)構(gòu)羽资,它類似于數(shù)組,但是成員的值都是唯一的瓮栗,沒有重復(fù)的值
初始化 Set 可以接受一個數(shù)組或類數(shù)組對象作為參數(shù)削罩,也可以創(chuàng)建一個空的 Set。
var s1 = new Set();
var s2 = new Set([1, 2, 3]);
console.log(s1);// Set(0) {}
console.log(s2);// Set(3) {1, 2, 3}
在 Set 中成員的值是唯一的费奸,重復(fù)的值自動被過濾掉弥激。
var s1 = new Set([1, 2, 2, 3, 1, 4]);
console.log(s1);// Set(4) {1, 2, 3, 4}
Set 的一些屬性方法:
size:返回成員總數(shù)
add(value):添加某個值,返回Set結(jié)構(gòu)本身
delete(value):刪除某個值愿阐,返回一個布爾值微服,表示刪除是否成功
has(value):返回一個布爾值,表示該值是否為Set的成員
clear():清除所有成員缨历,沒有返回值
var set = new Set([1,2]);
set.add(3);// 添加成員
console.log(set.size);// 3 成員總數(shù)
console.log(set);// Set(3) {1, 2, 3}
set.add([4,5]);// 添加成員
console.log(set.size);// 4 成員總數(shù)
console.log(set.has(2));// true 有該成員
console.log(set);// Set(4) {1, 2, 3, [4, 5]}
set.delete(2);// 刪除成員
console.log(set);// Set(3) {1, 3, [4, 5]}
console.log(set.has(2));// false 沒有該成員
set.clear();// 清除所有成員
console.log(set);// Set(0) {}
得益于數(shù)據(jù)結(jié)構(gòu) Set 查找更快速高效以蕴,但也因為數(shù)據(jù)結(jié)構(gòu)的內(nèi)部數(shù)據(jù)是無序的,無法實現(xiàn)按下標改查辛孵,排序等操作丛肮。
var arr = [1,2,3,'a',4,'b'];
var set = new Set(arr);
console.log(set[0]);// undefined
console.log(set['a']);// undefined
Map 是一個構(gòu)造函數(shù),用來生成 Map 數(shù)據(jù)結(jié)構(gòu)魄缚,它類似于對象宝与,也是鍵值對的集合焚廊,但是“鍵”可以是非字符串。
初始化 Map 需要一個二維數(shù)組习劫,或者直接初始化一個空的 Map咆瘟。
var m1 = new Map();
var m2 = new Map([['a', 123], ['b', 456], [3, 'abc']]);
console.log(m1);// Map(0) {}
console.log(m2);// Map(3) {"a" => 123, "b" => 456, 3 => "abc"}
Map 的一些操作方法:
set(key, value):設(shè)置鍵值對
get(key):獲取鍵對應(yīng)的值
has(key):是否存在某個鍵
delete(key):刪除某個鍵值對,返回一個布爾值诽里,表示刪除是否成功
var map = new Map([['a', 123], ['b', 456], [3, 'abc']]);
map.set('c',789);
console.log(map.get('c')); // 789
console.log(map.has('b')); // true 此key存在
map.delete(3); // true 成功刪除key
console.log(map); // Map(3) {"a" => 123, "b" => 456, "c" => 789}
傳統(tǒng) Object 只能用字符串作鍵袒餐,Object 結(jié)構(gòu)提供了“字符串 — 值”的對應(yīng)。
Map 結(jié)構(gòu)提供了“值 — 值”的對應(yīng)谤狡,是一種更完善的 Hash 結(jié)構(gòu)實現(xiàn)灸眼。
如果你需要“鍵值對”的數(shù)據(jù)結(jié)構(gòu),Map 比 Object 更快速 更高效 更合適豌汇。
遍歷Map和Set對象
var map = new Map([['a', 123], ['b', 456], [3, 'abc'],['c', 789]]);
map.forEach((val,key,obj)=>{
console.log('val: '+val);
console.log('key: '+key);
console.log(obj);
}); // 結(jié)果如下圖
var set = new Set(['a','b','c','d']);
set.forEach((val,key,obj)=>{
console.log('val: '+val);
console.log('key: '+key);
console.log(obj);
});// 結(jié)果如下圖
當然幢炸,還可以使用es6中的 for of 遍歷
var map = new Map([['a', 123], ['b', 456], [3, 'abc'],['c', 789]]);
for (const [key,val] of map) {
console.log(key+' : '+val);
}
// a : 123
// b : 456
// 3 : abc
// c : 789
var set = new Set(['a','b','c','d']);
for (const val of set) {
console.log(val);// a b c d
}
有沒有發(fā)現(xiàn) Set 沒有類似 get 的方法泄隔,怎么取值呢拒贱?
可以用上面的遍歷取值,或者可以把 Set 轉(zhuǎn)成真正的數(shù)組佛嬉。
第一種方法:使用擴展運算符把類似數(shù)組對象的 Set 展開并放在數(shù)組里逻澳。
var set = new Set(['a','b','c','d']);
var arr = [...set];
console.log(arr);// ["a", "b", "c", "d"]
第二種方法:使用 Array.from() 方法轉(zhuǎn)成真正的數(shù)組對象。
var set = new Set(['a','b','c','d']);
var arr = Array.from(set);
console.log(arr);// ["a", "b", "c", "d"]
小結(jié):
回歸主題暖呕,用一行代碼實現(xiàn)數(shù)組去重斜做,至此已解決。
利用 Set 內(nèi)部成員的唯一性不可重復(fù)性湾揽,再配合擴展運算符瓤逼,很輕松一行代碼搞定。
當我們在解決一個問題的時候库物,相關(guān)聯(lián)的知識點也應(yīng)該去學(xué)習(xí)霸旗,這樣進步更快一點。
es6 很多新特性真的即方便又高效戚揭。
作者:那木炫_
原文鏈接:https://blog.csdn.net/qq_36476745/article/details/81904156