基本操作
一维数组与二维数组互相转换
求余实现
//求余(%) 12%5返回2
let baseArray = [1, 2, 3, 4, 5, 6, 7, 8]
let len = baseArray.length
// 假设每行显示四个
let n = 4
// 求余
let lineNum = len % n === 0 ? len / n : Math.floor((len / n) + 1)
// let lineNum = Math.ceil(len/4)
let res =[]
for(let i=0;i<lineNum;i++){
// (0,4) (4,8)
let temp = baseArray.slice(i*n,i*n+n)
res.push(temp)
}
console.log(res) //[[1, 2, 3, 4],[5, 6, 7, 8]]
let baseArray = [1, 2, 3, 4, 5, 6, 7, 8]
// 假设每行显示四个
let n = 4
let res = []
baseArray.forEach((item,index)=>{
if(!res[Math.floor(index/n)]){
res[Math.floor(index/n)] =[]
}
res[Math.floor(index/n)].push(item)
})
console.log(res)
// (2) [Array(4), Array(4)]
// 0: (4) [1, 2, 3, 4]
// 1: (4) [5, 6, 7, 8]
递归法
function change2Array(data, len, arr) {
/**
* @param data 一维数组
* @param len 每个子数组长度
* @param arr 保存的新数组
*/
if (data.length <= len) {
arr.push(data);
console.log(arr)
return arr;
} else {
arr.push(data.splice(0, len));
change2Array(data, len, arr);
}
}
注意 splice push 都是会改变原数组的
二维数组转换为一维数组
const arr=[[1,2,3],[3,4],[5]];
var newarr = [].concat.apply([],arr)
console.log(newarr)
call 是不可以的
call 与 apply 的区别 传参的不同
let flattened = [[0,1],[1,2]].reduce(function(a,b){
return a.concat(b)
})
console.log(flattened) //[0, 1, 1, 2]
参考文档 https://segmentfault.com/a/1190000016038640
数组与字符串的相互转换 (Array String )
1) array 转换成 string
arr.toString()
let arr = ["111","222"]
console.log(arr.toString()) //111,222
let arr = ["111","222",[22]]
console.log(arr.toString()) //111,222,22
let arr = ["111","222",{"a":111}]
console.log(arr.toString()) //111,222,[object Object]
arr.join()
let arr = ["111","222",[22]]
console.log(arr.join(",")) //111,222,22
2)string 转换成 array
arr.split()
let arr = "111,222"
console.log(arr.split(",")) //["111", "222"]
数组降维
1.双重遍历二维数组中的每个元素并放到新数组中
function reduceDimension(arr){
var reduced = [];
for(var i=0;i<arr.length;i++){
for(var j=0;j<arr[i].length;j++){
reduced.push(arr[i][j])
}
}
return reduced
}
2.利用concat 转换
concat()不改变原数组 用于合并两个或多个数组 返回一个新数组
function reduceDimension(arr){
var reduced = [];
for(var i=0;i<arr.length;i++){
reduced = reduced.concat(arr[i])
}
return reduced;
}
3.利用apply 和 concat 转换
function reduceDimension(arr) {
return Array.prototype.concat.apply([], arr);
}
首字母大写
function ucFirst(arr){
return arr.slice(0,1).toUpperCase() + arr.slice(1)
}
ucFirst("ahello")
不能“替换”第一个字符,因为在js中字符串是不可变得
但是我们可以根据已有字符串创建一个首字母大写的新字符串
let newStr = str[0].toUpperCase() + str.slice(1)
存在问题 如果str是空的,那么str[0] 就是 undefined 但由于undefined 没有toUpperCase()方法
因此会得到一个错误
存在如下两种变体:
1.使用str.charAt(0) 因为它总是会返回一个字符串 (可能为空)
2.为空字符添加测试
function ucFirst(str) {
if (!str) return str;
return str[0].toUpperCase() + str.slice(1);
}
alert( ucFirst("john") ); // John
对数组中的图片地址处理
场景 服务器返回的图片地址 有的加上域名有的直接是图片在服务器上面的地址 需要进行处理
需要注意的是 结果是会返回一个新的数组
let urlbase = "http://www.baidu.com"
let a = ['1','http://www.xxx.xxx.png','3','4']
let newarr = a.map(function(value,index,arr){
if(value.includes('http')){
return value
}else{
return urlbase + value
}
})
console.log(newarr)
将数组中的字符串转换为数字
将字符串转换为数字
let arr = ["1","2","3","4"]
var res = arr.map(x=>Number(x))
console.log(res) // [1, 2, 3, 4]
console.log(typeof(res[0])) // number
取出 对象数组 中的值
实际应用 分类列表中 左边菜单的文字 在整个数据中取出重新组成单独的菜单数据
let data = [
{
title:"111",
children:[]
},
{
title:"111",
children:[]
}
]
var newarr = data.map(x=>x.title)
console.log(newarr) //["111", "111"]
求和问题
参数不固定
reduce arguments
reduce 只适用于 数组相加
function sum(...args){
return args.reduce((s,v)=>{
return s+=v
},0)
}
console.log(sum(1,2,3,4))
arguments
function sum(){
// console.log(arguments)
let total = null;
for(let i=0;i<arguments.length;i++){
//获取的每一项的结果都需要转换为数字(数学运算)
let item = Number(arguments[i])
//非有效数字不加
if(isNaN(item)){
continue
}
total += item
}
return total;
}
let total = sum(10,20)
console.log(total)
total = sum(10,20,"30")
console.log(total)
验证手机号
var reg = /^1[0-9]{10}$/;
常见数组的应用
判断某个数是不是奇数
判断某个数是不是素数
数组求和
数组中的最大值
数组中的最小值
数组是否是稀松数组
什么是稀松数组:数组的元素不是连续有值。
var arr=new Array(3);
arr[0] = 1
arr[2] = 3
其中arr[1]=undefined;
某年是否为闰年
//4年一闰,百年不闰;400年一闰
得到某年某月的天数
得到某个数字数组中出现次数最多的数字和频率
取出数组对象中的某些值重新组成一个新的数组
将下例的数据重新组成一个新的值得数组
let arr = [
{
name: "酒水",
seq: 0,
type: 102
},
{
name: "西瓜",
seq: 12,
type: 102
}
]
let newArr = []
arr.forEach(item=>{
newArr.push({
text:item.name,
value:item.seq
})
})
console.log(newArr)
生成指定范围的随机数
function getRandom(n, m) {
//生成[0,10]之间,在加上 70 即可
var num = Math.floor(Math.random() * (m - n + 1) + n)
return num
}
var number = getRandom(70,80)
console.log(number)
创建一个 [1…100]的数组
let arr = []
// push方法
for(let i = 1,len=100;i<=100;i++){arr.push(i)}
//循环赋值
for(let i = 1,len=100;i<=100;i++){arr[i-1]=i}
// Array.from()方法 后面会有一点点的优化
Array.from({length:101}, (v,k) => k)// or Array.from(Array(101), (v,k) =>k);
Array.from(Array(101).keys())
arr.splice(0,1)
[...Array(100).keys()]// 0-> 99
[...Array.from({length:100}).keys()]// 0-> 99
Array.from(new Array(100).keys())
// mdn 看见的 序列生成器(指定范围)
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => + (i * step));
range(1,100,1)// 1-> 100
Array.from({length:100},(_, i)=>1+(i)) // 1-> 100
实际应用-数组
投影数组
对某个值执行一个函数,以得到新的值,这种操作叫做投影。为了把一个数组投影成另一个数组,我们对数组中的每个元素都执行一个投影函数,然后把所有的结果收集起来,组成新的数组。
过滤数组
1.对数组中的值进行筛选过滤在重新组合
投影数组 场景: 把一个包含 video 信息的数组投影成包含{id,title}对的新数组
var newArr = message.map(item=>{
return {name:item.name}
})
//return item.name 返回的是一个数组
2.将数组中的值变成对象的键值 形式
for in 循环方式
let obj = {}
for(var item in message){
obj[message[item].value] = message[item].name
}
console.log(obj)
map循环方式
let obj = {}
var newArr = message.map(e=>{
obj[e.value] = e.name
})
console.log(obj)
3.根据数组中的某一项值进行排序
var message = [{
name: "个人待办",
value: "personal_standby",
order:1
},
{
name: "流程跟踪",
value: "process_tracking",
order:2
},
{
name: "应用推荐",
value: "application_recommendation",
order:4
},
{
name: "最新应用",
value: "latest_application",
order:3
},
{
name: "周期性应用",
value: "period_application",
order:5
},
{
name: "专题推荐",
value: "sbject_rommendation",
order:7
},
{
name: "收藏服务",
value: "collect_service",
order:6
}
]
//
function compare(p){
return function(a,b){
var value1 = a[p]
var value2 = b[p]
return value1 - value2
}
}
var res = message.sort(compare('order'))
console.log(res)
4.往数组中添加属性
map方法
var arr = message.map((item,index)=>{
item.id = index
return item //一定要在这儿return
})
console.log(arr)
Object.assign()
补充 Object.assign(target, …sources)
target 目标对象 sources 源对象
下面的写法等于是把 item 与 {mess:1} 进行组合
var array2 = []
message.map((item,index)=>{
array2.push(Object.assign({},item,{mess1:1}))
})
console.log(array2)
5.对数组中重复的值进行去重
var arr2 = [{
name: "name1",
num: "1"
},
{
name: "name2",
num: "11"
},
{
name: "name3",
num: "12"
},
{
name: "name4",
num: "13"
},
{
name: "name2",
num: "1"
},
{
name: "name6",
num: "12"
}
]
function arrayUnique2(arr,name){
var hash = {}
return arr.reduce(function(item,next){
hash[next[name]] ? '': hash[next[name]] = true && item.push(next)
return item
},[])
}
console.log(arrayUnique2(arr2,"name"))
//代码分析
hash[next[name]] = true && item.push(next)
将这个值作为一个记号进行标记
备注:上面的这个去重方法是取第一个出现的值,后面再有值的话是不会进行覆盖的。
如果要取最新的一个值该如何?
另一种方法
function unique(arr) {
const res = new Map();
return arr.filter((a) => !res.has(a.name) && res.set(a.name, 1))
}
console.log(unique(arr2))
数组去重
利用 es6 set去重
备注:set 的这种形式去重只能是 单个数组的形式,对象数组不适用。
var arr =[1,2,3,4,5,6,3,2,3]
function unique(arr){
return Array.from(new Set(arr))
}
console.log(unique(arr))
//也可以另一种形式的写法
var arr2 = [{
name: "name1",
num: "1"
},
{
name: "name2",
num: "11"
},
{
name: "name3",
num: "12"
},
{
name: "name4",
num: "13"
},
{
name: "name6",
num: "12"
}]
let res = [...new Set(arr2.map(item=>item.num))]
reduce 用法
文章链接
6.判断对象数组中是否存在某个对象
数组方法 some 判断
var arr = [{
name: "常用"
}, {
name: "1"
}]
var obj = {
name: "5"
}
var result = arr.some(item => {
if (this.obj.name === item.name) {
return true
}
})
if (result) {
console.log("已经存在")
} else {
this.arr.push(obj)
}
console.log(arr)
1.判断数组中是否存在耨个元素,indexOf()
var arr = [1,2,3,4]
console.log(arr.indexOf(3)) //2
console.log(arr.indexOf(8)) //-1
2.只判断情况下,可以遍历后判断对象的属性是否相同
arr.forEach(item=>{
if(item.name=='Alex'){
console.log('存在这个元素');
}
})
3.设一个flag来做判断的标识
var arr = [{
name: "常用"
}, {
name: "1"
}]
var obj = {
name: "1"
}
let flag = true
arr.forEach(item=>{
if(obj.name == item.name){
flag = false
}else{
flag = true
}
})
if(flag){
arr.push(obj)
}else{
console.log("已存在")
}
console.log(arr)
7.reduce 的高级使用
var result = [
{
subject: 'math',
score: 88
},
{
subject: 'chinese',
score: 95
},
{
subject: 'english',
score: 80
}
];
//for 循环
var sum = 0;
for(var i=0; i<result.length; i++) {
sum += result[i].score;
}
//reduce
var sum = result.reduce(function(prev, cur) {
return cur.score + prev;
}, 0);
//错误写法
var sum = result.reduce(function(prev, cur) {
return cur.score + prev.score ;
}, 0);
这个时候,我给reduce参数添加了第二个参数。通过打印我发现设置了这个参数之后,reduce遍历便已经从第一项开始了。 这第二个参数就是设置prev的初始类型和初始值,比如为0,就表示prev的初始值为number类型,值为0,因此,reduce的最终结果也会是number类型。
https://segmentfault.com/a/1190000005921341
flat()
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]
//使用 Infinity,可展开任意深度的嵌套数组
var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
扁平化与数组空项
flat() 方法会移除数组中的空项:
var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]
替代方案
使用 reduce 与 concat
var arr = [1, 2, [3, 4]];
// 展开一层数组
arr.flat();
// 等效于
arr.reduce((acc, val) => acc.concat(val), []);
// [1, 2, 3, 4]
// 使用扩展运算符 ...
const flattened = arr => [].concat(...arr);
相关文章
https://github.com/mqyqingfeng/Blog/issues/36
https://juejin.cn/post/6844903805876699150#heading-5
https://www.cnblogs.com/lynn-z/p/13915539.html
数组原理
1.map
Array.prototype.myMap = function (projectionFunction) {
var results = [];
this.forEach(function (item) {
return results.push(projectionFunction(item));
});
return results;
};
//test
var arr = [1, 2, 4, 5, 6, 7];
let newArr = arr.myMap(function (x) {
return x + 1;
});
console.log(newArr);
2.filter
为了让过滤操作更简单, 我们给数组类型添加一个 filter() 函数。 filter() 接受一个断言作为参数。 断言是这样一个函数: 它以数组中的一个元素作为参数,返回一个布尔值,表明这个元素应不应该被添加到新数组中。
Array.prototype.filter = function (predicateFunction) {
var results = [];
this.forEach(function (itemInArray) {
//看返回是不是 true
return predicateFunction(itemInArray) && results.push(itemInArray);
});
return results;
};