数组是什么

  1. 数组是按次序排列的一组值。
  2. 本质上,数组属于一种特殊的对象。typeof运算符会返回数组的类型是object。(万物皆对象)
  3. 数组属于复杂数据类型

数组·API剖析–不会改变原数组

欢迎收看新闻联播!接下来总结一下数组的相关操作…

判断是否为数组
  • instanceof

instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。

let arr1 = [1,2,3]
    console.log(arr1 instanceof Array) //true
  • isArray

Array.isArray(obj)用于确定传递的值是否是一个 Array

console.log(Array.isArray(arr1)) //true
  • typeof

typeof操作符返回一个字符串,表示未经计算的操作数的类型。typeof运算符会返回数组的类型是object。

console.log(typeof arr1) //"object"
object.valueOf()返回数组本身
console.log(arr1.valueOf())//[1,2,3]
arr.toString()一个表示指定的数组及其元素的字符串。
console.log(arr1.toString())//1,2,3
arr.join([separator])指定一个字符串separator来分隔数组的每个元素。

join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。常用

console.log(arr1.join(","))//1,2,3
indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1
console.log(arr1.indexOf(2,0))//结果返回为1,从索引值为0开始往后找
arr.lastIndexOf(searchElement[, fromIndex = arr.length - 1])

从此位置fromIndex开始逆向查找searchElement。返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找.
跟indexOf一样,都是返回查找元素在数组中的索引值,只不过它是往后查看的

console.log(arr1.lastIndexOf(1))
数组的链接
let array1 = ['a', 'b', 'c'];
let array2 = ['d', 'e', 'f'];
console.log(array1.concat(array2)) //["a", "b", "c", "d", "e", "f"]
console.log(array1) //["a", "b", "c"]

数组API–改变原来的数组

数组的常用方法
  • arr.push(element1, …, elementN) 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。
let arr2 = [1,2,3,4]
console.log(arr2.push(5)) //5
console.log(arr2) //  [1, 2, 3, 4, 5]
  • arr.pop() 数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。
let plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato'];
console.log(plants.length) // 5
console.log(plants.pop()) // tomato
console.log(plants) // (4) ["broccoli", "cauliflower", "cabbage", "kale"]
  • arr.unshift(element1, …, elementN) 将一个或多个元素添加到数组的开头,并返回该数组的新长度。
let arr3 = [1,2,3]
console.log(arr3.length) //3
console.log(arr3.unshift(2,5,6)) //6
console.log(arr3) // [2, 5, 6, 1, 2, 3]
  • arr.shift() 从前面删除一个元素 返回被删除的元素
let arr4 = [2,6,8,8]
console.log(arr4.shift()) //2
console.log(arr4) // [6, 8, 8]
数组排序
  • arr.sort([compareFunction]) 数组的排序.

sort() 方法用原地算法对数组的元素进行排序,并返回排序后数组。

let arr5 = [3,33,333,55,22,66]
console.log(arr5.sort()) // [22, 3, 33, 333, 55, 66]
console.log(arr5) // [22, 3, 33, 333, 55, 66]
// 为什么不是根据数字大小进行排序,因为默认排序顺序是根据字符串Unicode码点
console.log(arr5.sort(function (a,b) {
    return a - b;
})) //[3, 22, 33, 55, 66, 333]
  • arr.reverse() 方法将数组中元素的位置颠倒,并返回该数组。
let arr6 = [3,33,333,55,22,66]
console.log(arr6.reverse())  //[66, 22, 55, 333, 33, 3]
console.log(arr6) //[66, 22, 55, 333, 33, 3]
字符串删除和插入
  • array.splice(start[, deleteCount[, item1[, item2[, …]]]])
    start:指定修改的开始位置(从0计数)
    deleteCount:整数,表示要移除的数组元素的个数
    item1, item2, … 要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。
let arr7 = [3,33,333,55,22,66,666]
console.log(arr7.splice(1,2)) // 从数组索引1开始,删除2个元素,返回:[33, 333]
console.log(arr7) // [3, 55, 22, 66, 666]
console.log(arr7.splice(1,0,6)) //在数组索引1后面不删除元素(0||负数),并插入一个数字6,返回空数组
console.log(arr7) // [3, 6, 55, 22, 66, 666]

字符串的截取–不会改变原数组

  • arr.slice(begin, end)

begin可选。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。
end可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。

let animals = ['ant', 'bison', 'camel', 'duck', 'elephant']
console.log(animals.slice(2,4)) // ["camel", "duck"]
console.log(animals) // ['ant', 'bison', 'camel', 'duck', 'elephant']

数组循环–重磅

每一个方法都有它自己的特产,结合情况具体使用可以便利很多

foreach

一般用来循环数组,操作数组

let array1 = ['a', 'b', 'c'];
arr1.forEach((item,index)=>{
    console.log(`第${index+1}项是:`+item)
    // 第1项是:a  //  第2项是:b  // 第3项是:c
})

forEach() 方法对数组的每个元素执行一次提供的函数。作用跟for循环类型;只是它不能遍历dom节点。该方法返回undefined

filter

一般用来实现删除操作,过滤数组

let newArr1 = array1.filter((item,index)=>{
    if(item!=='a'){
        return false
    }
    return  true
})
console.log(newArr1) // ["a"]

filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。 返回一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。

let checkedArr = [true,false,true,false]
let newChecked = checkedArr.filter((item,index)=>!item)//将false返回
console.log(newChecked)//[false, false]
map

react比较常用,一般需要改变数组时使用

let array2 = [1, 4, 9, 16];
let newArr2 = array2.map((item,index)=> Math.sqrt(item)) //开根
console.log(newArr2) //  [1, 2, 3, 4]

map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。

some

一般用是checkbox radio全选和反选时

let array3 = ['1', '4', 9, '16'];
let newArr3 = array3.some((item,index)=> typeof item == "number")
console.log(newArr3) // true 

let array4 = ['1', '4', '9', '16'];
let newArr4 = array4.some((item,index)=> typeof item == "number")
console.log(newArr4) // false

some() 方法测试是否至少有一个元素通过由提供的函数实现的测试。(对于放在空数组上的任何条件,此方法返回false。)
只要满足条件返回一个“真值”(即可转换为布尔值 true 的值)。如果找到了这样一个值,some() 将会立即返回 true。否则,some() 返回 false。

every
let array5 = ['1', '4', '9', '16'];
let newArr5 = array5.every((item,inddex)=> typeof item == "string")
console.log(newArr5) //true

let array6 = ['1', '4', 9, '16'];
let newArr6 = array6.every((item,inddex)=> typeof item == "string")
console.log(newArr6) //false

every() 方法测试数组的所有元素是否都通过了指定函数的测试。
every 方法为数组中的每个元素执行一次 callback 函数,直到它找到一个使 callback 返回 false(表示可转换为布尔值 false 的值)的元素。如果发现了一个这样的元素,every 方法将会立即返回 false。否则,callback 为每一个元素返回 true,every 就会返回 true。

find
let array7 = [5, 12, 8, 130, 44];
let found = array7.find(item=>item > 10);
console.log(found) //12

find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。

findIndex
let array8 = [5, 12, 8, 130, 44];
let index = array8.findIndex(item=>item > 10);
console.log(index) //1

findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。

数组不常用方法

  • Array.of() 方法创建一个具有可变数量参数的新数组实例
console.log(Array.of(7))       // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array(7);          // [ , , , , , , ]
Array(1, 2, 3);    // [1, 2, 3]
  • Array.from() 方法从一个类似数组或可迭代对象中创建一个新的数组实例。
Array.from('foo');
// ["f", "o", "o"]
let s = new Set(['foo', window]);
Array.from(s);
// ["foo", window]

数组去重

  1. 利用es6 Set去重
    Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。Set对象是值的集合,你可以按照插入的顺序迭代它的元素。
let arr = [1,2,3,3,66,545,4,4,true,true,'true','1',undefined]
function unique1(array) {
    return Array.from(new Set(array))
}
console.log(unique1(arr))//[1, 2, 3, 66, 545, 4, true, "true", "1", undefined]

这种去重的方法代码最少,但是要考虑兼容方法。而且它们无法去掉复杂数据类型,因为复杂数据类型是地址值的引用

let arrData = [{},{},[1,23],[1,23]]
  1. 双层for循环
function unique2(array){
    for (var i = 0;i<array.length;i++){
        for (var j = i+1;j<array.length-1;j++){
            if(array[i]===array[j]){
                array.splice(i,1)
                break;
            }
        }
    }
    return array
}
  1. 利用indexOf去重
function unique3(array){
    let newArr = [] //定义一个新数组接收满足条件的数组
    for(var i = 0;i<array.length;i++){
        if(newArr.indexOf(array[i])===-1){
            newArr.push(array[i])
        }
    }
    return newArr
}
  1. 利用sort
    利用sort排序,然后在根据排序后的结果进行遍历以及相邻元素的比对
function unique4(array){
    let newArr = [array[0]]
    array.sort() //只要两个元素相同,它一定相邻
    for (var i = 1;i<array.length;i++){
        if(array[i-1]!==array[i]){
            newArr.push(array[i-1])
        }
    }
    return newArr
}
  1. 利用includes
    其实和上面的indexOf思考方式是差不多的,都是判断数组有没有包括该元素
function unique5(array){
    let newArr = [] //定义一个新数组接收满足条件的数组
    for(var i = 0;i<array.length;i++){
        if(!newArr.includes(array[i])){
            newArr.push(array[i])
        }
    }
    return newArr
}
console.log(unique5(arr))
  1. 利用filter
function unique6(array){
    return array.filter((item,index)=>{
        // 如果等于当前元素的索引值,则该元素满足条件
        return array.indexOf(item)===index
    })
}
  1. 利用Map数据结构去重
    一个Map对象在迭代时会根据对象中元素的插入顺序来进行 — 一个 for…of 循环在每次迭代后会返回一个形式为[key,value]的数组。
function unique7(array){
    let map = new Map()
    let newArr = []
    for (var i = 0;i<array.length;i++){
        if(map.has(arr[i])){
            map.set(arr[i],true)
        }else{
            map.set(arr[i],'该值已经第一次存在')
            newArr.push(array[i])
        }
    }
    return newArr
}
  1. 利用reduce+includes
    reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值
function unique8(array){
    return array.reduce((prev,cur)=>prev.includes(cur)?prev:[...prev,cur],[])
}
  1. 使用对象
function unique9(array){
    let newArr = []
    let obj = {}
    for(var i = 0;i<array.length;i++){
        if(!obj[arr[i]]){
            newArr.push(array[i])
            obj[arr[i]] = true //添加进数组,在令它存在
        }
    }
    return newArr
}

能去掉复杂数据类型,但是如果不全等,它无法去掉

其它去重
  1. 当然每一次最好都加一个判断语句
if(!array.length){

}
  1. 其它一些方法foreachfindIndex,lastIndexOf,map使用来去重等等都差不多和上面一致
  2. 也可以利用hasOwnProperty;指示对象自身属性中是否具有指定的属性.其实大同小异
  3. 或则使用while等等都是一样的

冒泡排序

for循环实现冒泡

var arr = [11, 2, 3, 1, 5, 10]
    for (var i = 0; i < arr.length; i++) {
        for (var j = 0; j < arr.length - 1 -i; j++) {
            //需要在判断条件arr.length-1;当j=arr.length-1;j+1不存在
            //还要在减掉i,因为最大的已经排好了,不需要在比较了
            var temp = arr[j]
            if (arr[j] > arr[j + 1]) {
                arr[j] = arr[j+1]
                arr[j+1] = temp//把最大的数移到最后面
            }
        }
    }
    console.log(arr)

利用sort

let arr = [11, 2, 3, 1, 5, 10]
arr.sort((a,b)=>{
    return a - b
})
console.log(arr)

es6

<!-- <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> -->