前端开发常用:JS对数组Array的操作

前端开发中请求接口返回数据通常伴随着对数组(对象数组)的处理

let arr1 = [1,3,5,2,4,6];
let arr2 = [
	{id:'1',name:'Banana'},
	{id:'2',name:'Apple'},
	{id:'3',name:'Orange'},
];
  1. 判断类型是否为数组
// ES6中提供了 Array.isArray() 方法,返回 true 或者 false。
Array.isArray(arr); 
// 如果不支持ES6,则使用它保证准确性
Object.prototype.toString.apply(arr) === '[object Array]'; 

/* 
其它相关内容:
	arr instanceof Array
	arr.constructor === Array
	Array.prototype.isPrototypeOf(arr1)
	Object.getPrototypeOf(arr) === Array.prototype
	Object.prototype.toString.apply(arr) === '[object Array]'
若修改对象的__proto__: Array.prototype,则前面四种都会出现问题
*/

  1. 然后开始遍历数组
// fori 循环
for (let i=0; i<arr.length; i++) {}
for (let i=0,len=arr.length; i<len; i++) {} // 若遍历中数组长度不变,应将长度保存为变量len,改进提高效率

// forEach循环,不支持break和return
arr.forEach(item=>{});

// for-of循环,可以return,break和continue
for (let item of arr) {}

/*
	forof支持Set和Map的遍历
	for (let item of new Set(arr)) {}
	for (let [key, value] of myMap) {}

	arr.forEach(function(self,index,arr){},this);
		self:数组当前遍历的元素,默认从左往右依次获取数组元素。
		index:数组当前元素的索引,第一个元素索引为0,依次类推。
		arr:当前遍历的数组。
		this:回调函数中this指向。
*/
/*
单独提一嘴forin
通常情况下会用来遍历对象的keys
	for(let key in someObject){
	 console.log(key + ": " + someObject[key]);
	}
	for (let key of Object.keys(someObject)) {
	  console.log(key + ": " + someObject[key]);
	}
*/
  1. map,filter和reduce方法
// map方法,对数组遍历并且返回一个新的数组。不给return,默认返回undefined
let mapArr = arr.map((item,index,arr)=>{});

// filter方法,用于返回符合条件元素的新数组
let filterArr = arr.filter(item=>{});

// reduce方法,迭代数组的每一项,并返回一个组合结果
let result= arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue]);

数组排序去重等其它需求

  1. 排序sort
    V8源码里,sort方法使用快速排序,当数组长度小于22,使用插入排序
// Number数组排序,sort方法默认升序排序
let nums = [1,3,5,2,4,6];
nums.sort((a,b) => a-b);
console.log(nums); // [1, 2, 3, 4, 5, 6]

// 对象数组排序(年龄)
let persons = [{name:'Big Banana',age:18},{name:'Cui Cui',age:24},{name:'Cong Cong',age:20}];
persons.sort((a,b) => a.age-b.age);
console.log(persons); // 18 -> 20 -> 24

/*
手写一个快速排序
	原理:在数据集之中,找一个基准点,建立两个数组,分别存储左边和右边的数组,利用递归进行下次比较。
	第1轮:[5,7,25,10,40],66,[99]
	第2轮:[5,7,10],25,[40],66,99
	第3轮:[5],7[10],25,40,66,99 ->return [5,7,10,25,40,66,99]
*/
function quickSort(arr) {
    if (!Array.isArray(arr)) return; // 使用上面的知识点,先判断如果不是数组则直接返回
    if (arr.length <= 1) return arr; // 出口,直接返回这个数组
    
    // 开始快排
    // step1:取数组中间的那个数为基准点
    let num = Math.floor(arr.length / 2); 
    let value = arr.splice(num, 1)[0];
    let left = [], right = [];// 定义两个数组
    // 遍历这个数组的每一项
    for (let i=0, len=arr.length; i<len; i++) {
        if (arr[i] > value) { // 比它大的放入right
            right.push(arr[i]);
        } else { // 小于等于基准点的放入left
            left.push(arr[i]);
        }
    }
    // 因为最终会返回[num],递归调用后通过...运算符展开
    return [...quickSort(left), value, ...quickSort(right)];
}

// 测试
let arr = [99,5,7,66,25,10,40];
let sortArr = quickSort(arr);
console.log(sortArr);
  1. 去重
// Number数组去重
let arr = [1,1,3,2,3,4,5,7,5,1,5];
// 通过es6的Set去重后,然后使用...运算符展开
arr = [...new Set(arr)];
console.log(arr);

// 对象数组去重(id)
function onlyOne(arr){
    if (!Array.isArray(arr)) return;
    let obj = {};
    let result = [];
    arr.forEach(item=>{
        if(!obj[item.id]){
            result.push(item);
            obj[item.id] = true;
        }
    });
    return result;
}

// 测试
let persons = [{id:1,name:'Big Banana'},{id:2,name:'Cui Cui'},{id:1,name:'Cong Cong'}];
let newArr = onlyOne(persons);
console.log(newArr);

/*
力扣算法题(删除排序数组的重复项):
        let arr = [1, 1, 2, 3, 4, 4];
        /**
         * 有序数组去重(方案一)
         * 使用一个新的数组来存放不重复的元素
         * 遍历判断当前元素是否在结果数组中存在(也就是item !== reslut[length-1])
         */
        function sortArrDuplicate1(arr) {
            if (!Array.isArray(arr)) return; // 先判断类型是否为数组
            if (arr.length < 2) return arr; // 若数组内只有一个元素直接返回就行了

            // 将第一个元素放入结果里面
            let result = [arr[0]];
            for (let i = 1; i < arr.length; i++) { // 从第二个元素开始遍历
                // 如果arr[i]和result[length-1]不相同,则放入result
                if (arr[i] !== result[result.length - 1]) result.push(arr[i]);
            }
            return result;
        }

        /**
         * 有序数组去重(方案2)
         * 双指针
         * 慢的指针用于记录当前位置是否可覆盖,快的指针用来遍历元素的每一项
         * 最后截取该可覆盖的长度
         */
        function sortArrDuplicate2(arr) {
            if (!Array.isArray(arr)) return;
            if (arr.length < 2) return arr;

            let i = 1;
            for (let j = i; j < arr.length; j++) {
                if (arr[j] !== arr[i-1]) {
                    arr[i] = arr[j];
                    i++
                }
            }
            return arr.splice(0,i)
        }
*/
  1. 两个数组找不同
/*
	思路:
		1.连接两个数组
		2.然后过滤出只出现过一次的元素
		3.也就是元素下标 arr.indexOf(v) === arr.lastIndexOf(v)
*/
let arr1 = [1,2,3,4,5],
	arr2 = [3,4,5,6,7];
let difference = arr1.concat(arr2).filter((v, i, arr) => arr.indexOf(v) === arr.lastIndexOf(v));
console.log(difference); // [1, 2, 6, 7]
  1. 字典对应(类似sql的左连接left join on)
// 很多时候会遇到在页面上显示内容时候需要将code,type等根据字典显示对应的中文
let dictionary = [
    {id:1,code:'001',name:'访客'},
    {id:2,code:'002',name:'普通会员'},
    {id:3,code:'003',name:'星级会员'},
];
let resData = [
    {id:1,name:'Big Banana',level:'003'},
    {id:2,name:'Cong Cong',level:'001'},
    {id:3,name:'Cui CUi',level:'002'},
];

// 1.将字典数组转换为key-value对象
let obj = {};
dictionary.forEach(item => {
    obj[item.code] = item.name;
});
// 2.遍历resData并进行匹配
resData = resData.map(item=>{
    item.level = obj[item.level];
    return item;
});
console.log(resData);
  1. 巧用reduce,用得越多会发现它越强大
// 1.数组求和
let arr = [1,3,5,7,9];
let sum = arr.reduce((sum,cur) => sum+=cur);
console.log(sum); //25

// 2.计算数组中每个元素出现的次数
let arr = ['a','b','i','g','b','a','n','a','n','a'];
let res = arr.reduce((obj,cur) => {
    if(cur in obj){
        obj[cur]++;
    }else{
        obj[cur]=1;
    }
    return obj;
},{});
console.log(res); // {a:4, b:2, g:1, i:1, n:2}

// 3.二维数组变一维数组
let arr = ['a',['b','i','g'],['b','a','n','a','n','a']];
let res = arr.reduce((arr,cur) => arr.concat(cur),[]);
console.log(res); // ["a", "b", "i", "g", "b", "a", "n", "a", "n", "a"]

// 4.对象数组分类统计,实现groupBy
function groupBy(objectArray, property) {
    return objectArray.reduce( (result, cur) =>{
        let key = cur[property];
        if (!result[key]) result[key] = [];
        result[key].push(cur);
        return result;
    }, {});
}

let resData = [
    {id:1,name:'Big Banana',level:'003'},
    {id:2,name:'Cong Cong',level:'001'},
    {id:3,name:'Cui CUi',level:'002'},
    {id:4,name:'Xiao Hu',level:'002'},
    {id:5,name:'Ji Lao Jun',level:'003'},
];
let data = groupBy(resData, 'level');
console.log(data);

some() 和 includes()

/*
	两个方法都返回一个布尔值
	includes用于基本数据类型的快速判断是否存在
	some方法传入一个函数,可以对对象数组进行判断是否存在
*/
const arr = [1,2,4,5,7,8,9]
console.log(arr.includes(1)) // true
console.log(arr.some(item=>item===10)) // false

find(),some()和filter()

const arr = ['1','2','3','4','5'];

// some方法:对数组中的特定元素进行匹配。返回的true或false
let isExist = arr.some(item=>item==='1');
console.log(isExist); // true

// find方法:在数组中找到符合条件的元素。找到就停止计算,并返回改元素;反之则返回undefined
// findIndex方法:和find相比就是返回值不同,返回目标元素下标,没有则为-1
let el = arr.find(item=>item==='1');
console.log(el); // '1'

// filter方法用于过滤出所有符合条件的元素。会遍历每一个元素,返回结果是一个新的数组 || []
let newArr = arr.filter(item=>item==='1');
console.log(newArr ); // ['1']

/*
总结:
	数组中是否存在某个元素时,使用some方法
	精准查找数组元素时,使用find方法
	从数组中筛选出一个新的数组时,用filter方法
*/

数组扁平化 flat

/* 
	该flat()方法创建一个新数组。
	其中所有子数组元素都以递归方式连接到该数组中,直到达到指定的深度。
	默认deep=1,传入Infinity,无需知道被扁平化的数组的维度。
*/
let arr1 = ['bb','cc','hh'], arr2 = ['yy',['tt',['oo']]];
let newArray = arr1.concat(arr2).flat(Infinity)
console.log(newArray)
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值