不久前,一个做后端的朋友和我聊天时,对我说了一句:”我才知道原来js是有Set这种数据结构的。”
“早就出了呢。”我随口应和道,有点心虚,也就是ES6才出的,不过也好几年了,算是蛮早了吧:)
后来,我们就聊了聊这个Set,还别说,我还没有怎么用过这个东西。我就知道它可以去重:
[...new Set([1,2,2,3])] // [1, 2, 3]
然后我们又聊到了:如果自己写这个去重呢?
嘿,这我还真写过:
[1,2,2,3].filter((value, index, arr) => {
return index === arr.indexOf(value)
})
// [1, 2, 3]
这里主要利用了indexOf
只会返回元素第一次出现的索引,这个很关键。
后来,我们又聊到:如果我们不去重了,就要看看这个数组里重复次数最多的是哪个元素呢?有点耿直是吧:)
嘿,这我也写过:
var arr = [1,2,3,4,3,2,2];
var arr_temp = [];
arr.map(value => {
if(arr_temp[value] !== undefined) {
arr_temp[value] += 1;
} else {
arr_temp[value] = 1;
}
})
for(let i = 0; i < arr_temp.length; i++) {
if(!arr_temp[i]) {
arr_temp[i] = 0;
}
}
console.log(arr_temp) // [0, 1, 3, 2, 1] console.log(Math.max(...arr_temp)) // 3
这边可能有一个疑问,就是为什么最后那个不用map而用基本的for循环,这是因为map不会对undefined的元素做处理:
var newArr = []
newArr[3] = 1
newArr.map((value,index)=>{
console.log('index ===', index)
if(newArr[index]===undefined) newArr[index] = 1;
else newArr[index] = value
})
// index === 3
是不是感觉不错,出来了,思路也挺好的?
但是呢,这有一个问题,如果arr里面有一个极大的数,那就会浪费新数组很大的空间,比如:
arr = [1,2,2,1000,3];
那么新的数组长度就变成了1000了呢。很僵硬。
还好,有一个改进的方法:
var arr = [1,2,3,4,3,2,2];
var arr_temp = {};
arr.map(value => {
if(arr_temp[value] !== undefined) {
arr_temp[value] += 1;
} else {
arr_temp[value] = 1;
}
})
console.log(arr_temp) // {1: 1, 2: 3, 3: 2, 4: 1} console.log(Math.max(...Object.values(arr_temp))) // 3
利用对象实现,是不是很赞!
后来,我们又聊到了这种方式可以用在LeetCode上的一个简单的题目,叫两数求和:
给一个整数数组和一个数字,求数组中是否有两个元素之和等于该数字?
function get2num(arr, n) {
let arr_temp = [];
let hasNum = 0;
arr.map(value => arr_temp[value]=1);
arr.map((value, index) => {
if(arr_temp[n-value] === 1 && value !== n-value){
hasNum = 1;
console.log('num ===', value, n-value);
}
})
if(!hasNum) {
console.log('no such 2 num');
}
}
get2num([1,9,6,8,4], 8)
// no such 2 num
get2num([1,2,6,8,4], 8)
// num === 2 6 // num === 6 2
就很好:)