数组相关
常用的数组api
- 改变原数组:尾部删除
pop()
,尾部添加push()
,头部删除shift()
,头部添加unshift()
,排序sort()
,颠倒数组元素reverse()
,删除或插入元素splice()
; - 不改变原数组:合并数组
concat()
,拼接数组元素join()
,截取元素slice()
,indexOf()
,lastIndexOf()
,toString()
forEach
(遍历所有元素)
let arr = ['a', 'b', 'c', 'd'];
arr.forEach(function (item, index) {
console.log(item + ',' + index);
})
map
(对数组进行重新组装,生成新的数组)
// map,生成新数组,不改变原来数组的格式
var arr = ['a', 'b', 'c', 'd'];
var result = arr.map(function (item, index) {
return index + '/' + item;
})
console.log(result);
sort
(对数组进行排序)
// sort, 会改变原来数组
var arr = [1, 23, 3, 4];
var result = arr.sort(function (a, b) {
// 从小到大排序
return a - b;
// 从大到小排序
// return b - a;
})
console.log(result);
filter
(过滤符合条件的元素)
var arr = [1, 2, 3, 4];
var result = arr.filter(function (item, index) {
if (item < 3) {
return true
}
})
console.log(result);
every
(判断所有元素是否都符合要求)
var arr = [1, 2, 3, 4];
var result = arr.every(function (item, index) {
if (item < 3) {
return true
}
})
console.log(result); // false
some
(判断是否有至少一个元素符合条件)
var arr = [1, 2, 3, 4];
var result = arr.some(function (item, index) {
if (item < 3) {
return true
}
})
console.log(result); // true
join
(根据条件对数组组合成字符串)
var arr = [1, 2, 3, 4];
var result = arr.join(',');
console.log(result);
reverse
(将数组反转)
var arr = [1, 2, 3, 4];
var result = arr.reverse();
console.log(result);
数组去重
- 1.利用
ES6
Set
去重(ES6
中最常用)
Array.from(new Set(arr));
[...new Set(arr)];
- 2.利用
for
嵌套for
,然后splice
去重(ES5
中最常用)
function unique(arr) {
for(let i = 0; i < arr.length; i++) {
for(let j = i + 1; j < arr.length; j++) {
if(arr[i] == arr[j]) { // 第一个等同于第二个,splice方法删除第二个
arr.splice(j,1);
j--;
}
}
}
return arr;
}
- 3.利用indexOf/includes去重
function unique(arr) {
var array =[];
for (let i = 0; i < arr.length; i++) {
if (array.indexof(arr[i]) === -1) { // 也可以用 array.includes(arr[i]) 作为判断条件
array .push(arr[i])
}
}
return array;
}
- 4.利用sort()
function unique(arr) {
if (!Array.isArray(arr)) {//先判断是否是数组
console.log('type error!')
return;
}
arr = arr.sort()
var arrry= [arr[0]];
for (var i = 1; i < arr.length; i++) {
if (arr[i] !== arr[i-1]) {
arrry.push(arr[i]);
}
}
return arrry;
}
- 5.利用filter
function unique(arr) {
return arr.filter(function(item, index, arr) {
return arr.indexof(item,0) === index;
});
}
- 6.利用递归去重
function unique(arr) {
var array= arr;
var len = array.length;
array.sort();
function loop(index){
if(index >= 1) {
if(array[index] === array[index-1]){
array.splice(index,1);
}
loop(index - 1); //递归loop,然后数组去重
}
}
loop(len-1);
return array;
}
- 7.利用reduce+includes
function unique(arr) {
return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);
}
- 8.利用hasOwnProperty
function unique(arr) {
var obj = {};
return arr.filter(function(item, index, arr){
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}
- 9.利用Map数据结构去重
function unique(arr) {
let map = new Map();
let array = new Array(); // 数组用于返回结果
for (let i = 0; i < arr.length; i++) {
if (map.has(arr[i])) { // 如果有该key值
map.set(arr[i], true);
} else {
map.set(arr[i], false); // 如果没有该key值
array.push(arr[i]);
}
}
return array;
}
filter()、map()和reduce()
- filter()
- 功能:顾名思义,
filter
就是过滤器的意思。它用于把Array
的某些元素过滤掉,然后返回剩下的元素 - 参数:接收一个函数作为其参数
- 特点:数组方法,传入的函数必须返回
boolean
值。它能把传入的函数依次作用于每个元素,然后根据返回值是true
还是false
决定保留还是丢弃该元素 - 用法:例如需获取数组中大于60的数字,只需要将大于60设定为过滤条件即可。代码如下:
const numbers=[12,54,77,120,20,302] //定义一个数组,里面有一些无序的数字
let newNums1 = numbers.filter(n => n > 60)
console.log(newNums1)//[77,120,302]
- map()
- 功能:
map
有 映射 的意思,也就是这个函数的功能。它用于将Array
中的所有元素进行一致的改变 - 参数:接收一个函数作为其参数
- 特点:数组方法。它能把传入的函数依次作用于每个元素,并把结果生成一个新的
Array
- 用法:需将新数组乘以2,那使用
map()
再合适不过了。代码如下:
let newNums2 = newNums1.map(n => n * 2)
console.log(newNums2)//[154,240,604]
- reduce()
- 功能:它用于把一个函数作用在这个
Array
的每一个元素上,然后把结果继续和序列的下一个元素做累积计算 - 参数:接受一个函数作为其参数,该函数要求有两个参数,第一个参数用于保存当前累积计算的值,第二个参数则是当前的数组元素
- 特点:数组方法。它可用于对数组的所有元素进行汇总
- 用法:得到数组的总和,即可使用
reduce()
。代码如下:
let total = newNums2.reduce((value,n) => value + n)
console.log(total)//998
- 例子
const numbers=[12,54,77,120,20,302] //定义一个数组,里面有一些无序的数字
//接下来相对这个数组的数据进行一些操作
//比如说获取该数组中大于60的数字,并对其乘以2,然后求他们的总和
//啥也不会的我一开始是这样做的
const moreThan60 = (arr) => {
let newNums = []
let total = 0
let j = 0
for (let i in arr) {
if (arr[i] > 60) {
newNums[j] = arr[i] * 2
total = total + newNums[j]
j++
}
}
return total
}//定义一个函数来实现
console.log(moreThan60(numbers)) //998
进阶
let total = numbers.filter(n => n > 60).map(n => n * 2).reduce((value,n) => value + n)
console.log(total)//998
对于
filter()
的补充
filter()
接收的回调函数,其实可以有多个参数。通常我们仅使用第一个参数,表示 Array 的某个元素。回调函数还可以接收另外两个参数,分别表示元素的位置和数组本身
const arr = ['a','b','c']
arr.filter((element,index,arrSelf) => {
console.log(element)//依次打印a b c
console.log(index)//依次打印0 1 2
console.log(arrSelf)//依次打印['a','b','c']
return true //返回一个布尔值
})
数组降维
- 1.数组字符串化
var arr = [[222,333,444,], [55,66,77],{a:1}];
arr += '';
arr = arr.split(',');
console.log(arr); // [222,333,444,55,66,77,[object Object]]
- 2.递归
function reduceDimension(arr) {
let ret = [];
let toArr = function(arr) {
arr.forEach((item) => {
item instanceof Array ? toArr(item) : ret.push(item);
});
}
toArr(arr);
return ret;
}
- 3.Array.prototype.flat()
var arr1 = [1, 2, [3, 4]];
arr1.flat(); // [1, 2, 3, 4]
var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat(); // [1, 2, 3, 4, [5, 6]]
var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2); // [1, 2, 3, 4, 5, 6]
//使用工nfinity作为深度,展开任意深度的嵌套数组
arr3.flat(Infinity); // [1, 2, 3, 4, 5, 6]
数组遍历
- 1.for循环
var arr = [1, 2, 3, 4, 5, 6];
var len = arr.length;
for(var i = 0; i < len; i++) {
console.log(arr[i]);
} // 1 2 3 4 5 6
- 2.for in
主要是用来循环遍历对象的属性,用来遍历数组效率最低(输出的
key
是数组索引
)
var arr = ['我', '是', '谁', '我', '在', '哪'];
for(var key in arr) {
console.log(key);
} // 0 1 2 3 4 5
- 3.for of(ES6)
性能要好于
for…in…
,但仍然比不上普通的for
循环(不能循环对象)
var arr = ['我', '是', '谁', '我', '在', '哪'];
for(var key of arr) {
console.log(key);
} // 我 是 谁 我 在 哪
- 4.foreach
数组自带的遍历方法,使用频率略高,但是性能仍然比普通循环略低
var arr = [1, 2, 3, 4, 5, 6];
arr.forEach(function (item, idnex, array) {
console.log(item); // 1 2 3 4 5 6
console.log(array); // [1, 2, 3, 4, 5, 6]
})
- 5.map
遍历每一个元素并且返回对应的元素(可以返回处理后的元素) ,返回的新数组和旧数组的长度是一样的,使用比较广泛,但其性能差于
forEach
var arr = [1, 2, 3, 4, 5, 6];
var newArr = arr.map(function (item, idnex) {
return item * item;
})
console.log(newArr); // [1, 4, 9, 16, 25, 36]
实现数组的随机排序
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
function randSort1(arr) {
for (var i = 0, len = arr.length; i < len; i++) {
var rand = parseInt(Math.random() * len);
var temp = arr[rand];
arr[rand] = arr[i];
arr[i] = temp;
}
return arr;
}
console.log(randSort1(arr));
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
function randSort2(arr) {
var mixedArray = [];
while (arr.length > 0) {
var randomIndex = parseInt(Math.random() * arr.length);
mixedArray.push(arr[randomIndex]);
arr.splice(randomIndex, 1);
}
return mixedArray;
}
console.log(randSort2(arr));
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.sort(function () {
return Math.random() - 0.5;
})
console.log(arr);
合并数组
如果你需要合并两个数组的话,可以使用 Array.concat()
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
console.log(array1.concat(array2)); // [1,2,3,4,5,6];
然而,这个函数并不适用于合并大的数组,因为它需要创建一个新的数组,而这会消耗很多内存
这时,你可以使用 Array.push.apply(arr1, arr2)
来代替创建新的数组,它可以把第二个数组合并到第一个中,从而较少内存消耗
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
console.log(array1.push.apply(array1, array2)); // [1, 2, 3, 4, 5, 6]
将数组换成前端更易解析的树状结构
function getTree(data) {
var newData = [],
hash = {};
for (var i = 0; i < data.length; i++) {
if (!hash[data[i].province]) {
hash[data[i].province] = {
'province': data[i].province
};
hash[data[i].province]['city'] = [{
'name': data[i].city,
'code': data[i].code
}]
newData.push(hash[data[i].province]);
} else if (hash[data[i].province].province == data[i].province) {
hash[data[i].province]['city'].push({
'name': data[i].city,
'code': data[i].code
})
}
}
return newData;
}
var data = [{
'province': '浙江',
'city': '温州',
'code': '10010'
}, {
'province': '浙江',
'city': '杭州',
'code': '10011'
}, {
'province': '安徽',
'city': '合肥',
'code': '10012'
}, {
'province': '安徽',
'city': '马鞍山',
'code': '10013'
}, {
'province': '浙江',
'city': '宁波',
'code': '10014'
}];
console.log(getTree(data));
Boolean过滤数组中的所有假值
let arr = [ 1 , null , false , 2 , 3 , NaN , '' ]
console.log(a.filter(Boolean)) //[1,2,3]