总结一些日常开发中对数组的操作
数组洗牌
1.首先需要一个取随机数的函数
function random(min,max){
return Math.floor(Math.random() * (max - min + 1) + min)
}
2.打乱数组
function shuffle(arr){
let _arr = arr.slice(arr);
for (let i=0 ;i<_arr.length; i++) {
const randomNum = random(0,i),
num = _arr[i];
_arr[i] = _arr[randomNum];
_arr[randomNum] = num;
};
return _arr;
} ;
shuffle([1,2,3,4,5,6,7,8]) // [7, 5, 3, 1, 8, 2, 6, 4]
取数组交集
function unionSet() {
let arr = [];
[...arguments].reduce((q, c) => {
if (!q instanceof Array) {
throw new Error('参数必须是数组');
return;
};
let _arr = [...new Set(q)],
_nextarr =[...new Set(c)];
_arr.forEach(v => {
_nextarr.includes(v) ? arr.push(v) : ''
});
_nextarr.forEach(v => {
_arr.includes(v) ? arr.push(v) : ''
});
});
return [...new Set(arr)];
}
unionSet([1,2,3],[3,2,1]) // [1,2,3]
取数组并集
function interSectionSet() {
return [...new Set([...arguments].reduce((q, c) => {
if (!q instanceof Array) {
throw new Error('参数必须是数组');
return;
};
return [...q, ...c]
}))];
};
interSectionSet([1,2,3],[3,4,5]) // [1,2,3,4,5]
取数组差集
function diffSet() {
let arr = [];
[...arguments].reduce((q, c) => {
if (!q instanceof Array) {
throw new Error('参数必须是数组');
return;
};
let _arr = [...new Set(q)],
_nextarr = [...new Set(c)];
_arr.forEach(v => {
_nextarr.includes(v) ? '' : arr.push(v)
});
_nextarr.forEach(v => {
_arr.includes(v) ? '' : arr.push(v)
});
});
return [...new Set(arr)];
}
diffSet([1,2,3],[3,4,5]) // [1,2,4,5]
数组去重
- 使用ES6的
Set
对象。Set
数据结构不含有重复的值,可以利用这个特性对数组去重。let arr = [1,2,4,5,3,4,5,'hello', 'hello'] function unDuplicateArray(arr) { let set = new Set(arr) return [...set] } let newarr = unDuplicateArray(arr) // [1, 2, 4, 5, 3, "hello"]
- 创建新数组,以不重复的方式加入到新数组中,然后返回该数组。
let arr = [1,2,4,5,3,4,5,'hello', 'hello'] function unDuplicateArray(arr) { let tmp = [] for(let ele of arr) { if(!tmp.includes(ele)) { tmp.push(ele) } } return tmp } let newArr = unDuplicateArray(arr) // [1, 2, 4, 5, 3, "hello"]
- 看到别人说的还有一种利用键值反转再反转的方式去重。看代码。
let arr = [1,2,4,5,3,4,5,'hello', 'hello'] function unDuplicateArray(arr) { let tmp = [] for(let ele of arr) { tmp[ele] = 1 } let newTmp = [] for(let n of tmp.values()) { newTmp.push(n) } return newTmp } let newArr2 = unDuplicateArray(arr) // ["1", "2", "3", "4", "5", "hello"]
可以看出,这种方法不可行,因为传给对象的键名会自动转换成字符串,所以原来的数值类型的元素都成了字符串。 但是,自从有了ES6的
Map
,情况就不一样了。Map
也是存储”键值对”的数据结构,但是它的键名可以是任意类型的。let arr = [1,2,4,5,3,4,5,'hello', 'hello'] function unDuplicateArray(arr) { let tmp = new Map() for(let ele of arr) { tmp.set(ele, 1) } return [...tmp.keys()] } let newArr2 = unDuplicateArray(arr) // [1, 2, 4, 5, 3, "hello"]
代码也简洁了许多。能用
Map
的地方,肯定可以用Set
,所以还是Set
更简单。 - 以上方法都是需要改变原数组的引用地址的。也就是说,如果之前将这个数组共享给了其他变量,那么这样对数组的更改无法反映到之前的变量中。想要对数组本身做修改,可以利用
indexOf()
方法。let arr = [1,2,4,5,3,4,5,'hello', 'hello'] function unDuplicateArray(arr) { let i = 0; for(i = 0;i<arr.length;i++){ let fromIndex = i+1 let findIndex = arr.indexOf(arr[i], fromIndex) console.log("1:"+findIndex) while(findIndex != -1){ console.log("2:"+findIndex) arr.splice(findIndex, 1) fromIndex = findIndex findIndex = arr.indexOf(arr[i], fromIndex) } } } newArr2 = unDuplicateArray(arr) // [1, 2, 4, 5, 3, "hello"]
- 将原数组的值作为对象的key,然后检测对象的key来判断是否加入新数组
let arr = [1,2,4,5,3,4,5,'hello', 'hello'] function unDuplicateArray(arr) { let _arr = [], obj = {}; for(let i of arr){ if(!obj[i]){ _arr.push(i); obj[i] = true } }; return _arr }; newArr2 = unDuplicateArray(arr) // [1, 2, 4, 5, 3, "hello"]