数组相关

常用的数组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()

  1. 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]
  1. map()
  • 功能:map 有 映射 的意思,也就是这个函数的功能。它用于将 Array 中的所有元素进行一致的改变
  • 参数:接收一个函数作为其参数
  • 特点:数组方法。它能把传入的函数依次作用于每个元素,并把结果生成一个新的 Array
  • 用法:需将新数组乘以2,那使用 map() 再合适不过了。代码如下:
let newNums2 = newNums1.map(n => n * 2)
console.log(newNums2)//[154,240,604]
  1. reduce()
  • 功能:它用于把一个函数作用在这个 Array 的每一个元素上,然后把结果继续和序列的下一个元素做累积计算
  • 参数:接受一个函数作为其参数,该函数要求有两个参数,第一个参数用于保存当前累积计算的值,第二个参数则是当前的数组元素
  • 特点:数组方法。它可用于对数组的所有元素进行汇总
  • 用法:得到数组的总和,即可使用 reduce()。代码如下:
let total = newNums2.reduce((value,n) => value + n)
console.log(total)//998
  1. 例子
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]