求数组的和:
数组求和是数组常见的问题,下面介绍两种数组求和的方法:
1.forEach
// 求和 forEach
let arr =[1,6,7,9,2,5,7]
let num = 0
// 定义一个新的数组并且让他的初始值为0
arr.forEach(item => num+=item)
console.log(num);
打印结果为;
用forEach求数组的和时,关键在于定义新数组接受时初始值一定要赋 0.
2.reduce
// reduce
let arr1 = arr.reduce((acc,idx) => acc + idx ,0)
console.log(arr1);
打印结果:
在我个人的理解中,reduce的用法在其实和常见的forEach、map一样都是用于遍历,只不过reduce需要设置初始值,增强了代码的可读性。
这里就介绍一下reduce的用法。
参数介绍:
arr.reduce((acc,item,index,arr) =>{
},init)
acc:初始值。(必需写的参数,这里是形参,你想叫啥名都行,希望不是part)
item:元素
index:索引
arr:数组对象
init:传递给函数的初始值,也就是acc的初始值。
3、这里就引出数组的常见问题也是reduce的用法之一
去重
3.1基本类型去重:
reduce
let arr = [1,2,3,4,6,8,1,7,6,2]
// let arr1 = []
let arr1 = arr.reduce((acc,item) => {
!acc.includes(item) && acc.push(item)
// 判断数组是否包含arr的元素,包含返回true,不包含返回false,这里取反, 也就是
// 不包含返回true并且把元素添加到新数组中,如果出现重复元素返回false,就不会添加
到新数组
return acc
},[])
console.log(arr1);
这里用到了数组方法includes():判断数组是否有指定的元素,有就返回true,没有返回false。
forEach
arr.forEach(item => {
if (arr1.indexOf(item) == -1) {
// 从前往后遍历数组,如果有指定的元素返回他的第一个的索引,没有就返回-1
arr1.push(item)
}
} )
arr.forEach(it=>{
if(arr1.includes(it)) return
arr1.push(it)
} )
3.2复杂类型去重
let list = [
{
subject: "数学",
marks: 80
},
{
subject: "语文",
marks: 90
},
{
subject: "英语",
marks: 80
},
]
function arrSet(value,arr) {
let obj = {}
let res = arr.reduce((pre, cur) => {
if (!obj[cur[value]]) {
obj[cur[value]] = true
pre.push(cur)
}
return pre
}, [])
return res
}
let result = arrSet("marks",list);
console.log(result); //[{subject:"数学",marks:80},{subject:"语文":90}]
3.3求最大值和最小值
let arr = [9,2,6,8,5]
let arr1 = arr.reduce((acc,item) =>{
return Math.max(acc,item)
})
let arr2 = arr.reduce((acc,item) =>{
return Math.min(acc,item)
})
console.log(arr1,arr2); // 打印结果9 2
3.4 扁平数组
二维数组转化为一维数组
let arr = [[1, 2, 8], [3, 4, 9], [5, 6, 10]];
let res = arr.reduce((arr, item) => {
return pre.concat(item)
},[]);
console.log(res) // [1, 2, 8, 3, 4, 9, 5, 6, 10]
多维数组转化为一维数组
let arr = [[1, [2, 8]], [3, 4, 9], [5, [6, 10]]]
function fn(arr) {
return arr.reduce((acc, item) => {
return acc.concat(Array.isArray(item) ? fn(item) : item)
}, [])
}
let newArr = fn(arr);
console.log(newArr);
// 打印结果[1, 2, 8, 3, 4, 9, 5, 6, 10]
4、挑选出数组中对象指定的值,并且把给定条件的值按规定相隔
// 把所有status 为true的 过滤出 拿到拼接的name 最终效果 奥特曼1,奥特曼3,奥特曼4
let arr = [{
name: '奥特曼1',
id: 1,
status: true,
}, {
name: '奥特曼2',
id: 2,
status: false,
}, {
name: '奥特曼3',
id: 3,
status: true,
}, {
name: '奥特曼4',
id: 3,
status: true,
}, {
name: '奥特曼5',
id: 3,
status: false,
}]
let arr2 = []
arr.filter((item,index) => {
if(item.status ==true) {
arr2.push(item.name)
}
})
arr3=arr2.join(',')
console.log(arr2);
打印结果:
5.在字符串内容中拿到指定的内容
// 结果 我要拿到 路由重定向
let url = 'https://so.csdn.net/so/search?spm=1001.2014.3001.4501&q=路由重定向&t=&u='
let arr = url.match(/[路由重新定向]/g)
console.log(arr);
这是我在看到这个问题的时候第一时间想到的解决办法,在经过实践之后我发现这种用正则表达式加match方法有一定的局限性,如果字符串中拿去的内容没有重复的话可以获取成功,但是在加g用全局查找之后还是会出现其他的问题,所以在碰见更复杂的字符串内容获取的话我推荐下面的方法。
// 结果 我要拿到 路由重定向
let url = 'https://so.csdn.net/so/search?spm=1001.2014.3001.4501&qqqqq=路由重定向&t=&u='
let arr = url.split('&')[1].split('=')[1]
console.log(url,arr);
通过字符串中特定符号把字符串分割成几部分在获取。
6. 一个随机数, 按指定顺序插入到数组中
// 产生一个 1-10的随机数 如果说这个随机数是1 那结果就是 [1,2,4,5]
let arr = [2, 4, 5]
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(getRandom(1, 10));
let arr1= arr.push(getRandom(1,10))
console.log(arr);
let arr2 = arr.sort((a,b) => a-b);
console.log(arr2);
打印结果:
给定的问题是把1-10的随机数插入到数组中按顺序排列,我第一时间想到能不能封装个函数,设定他的在最大值和最小值之前随机取整。Math这个内置对象封装了大部分和数学运算和属性相关的,只要你数学好,这种数学问题一般非常简单,别像我一样脑瘫到想到去封装一个函数就行。
下面说一个简单的方法:
// 产生一个 1-10的随机数 如果说这个随机数是1 那结果就是 [1,2,4,5]
let arr = [2,4,5]
let num = Math.ceil(Math.random()*10)
arr.unshift(num)
console.log(arr.sort((a,b)=>a-b));
这里对数组元素的排序用到了sort()方法,sort()方法通常分为两种情况。无参时,数组里面会按照默认编码进行排列,有参数时,会按照自定义排序规则排序。这里a-b就是按照升序排列,如果是b-a就是按照降序排列。