第四章 JavaScript 数组挖掘

守給你的承諾、 提交于 2020-02-08 22:17:32

1.值类型与引用类型

值类型会指向同一个内存地址,而引用类型不会。

let array = [1,2,3,4]
let msg = array
msg[1] = "weizhuren"
console.log(msg)//[1, "weizhuren", 3, 4]
console.log(array)//[1, "weizhuren", 3, 4]
console.table(array)//以表格形式打印

let a = 99 
let b = a
b++
console.log(a,b)//99 100

2.多维数组操作

多为数组可以使用以下方式定义,但是在开发过程中我们通常使用数组内定义对象的方式。

let array = ["wei",["zhu","ren"]]
console.log(array[1][1])
let msg = [{name:"weizhuren",department:"erbihou"}]
console.log(msg[0].name)

3.Array.of与数组创建细节

如果在一个长度为n的数组中新增加一个n+m(m>1)的元素,那么中间没有定义的元素会全部定义为undefined。

let array = ["weizhuren"]
array[2] = "erbihou"
console.log(array)//["weizhuren", empty, "erbihou"]
console.log(array[1])//undefined

使用new Array创建数组时,如果只有一个参数,那么将会创建这个参数数量的空元素。

let msg = new Array(1,2,3)
let msg1 = new Array(6)
console.log(msg.length,msg1.length)//3 6
console.log(msg)// [1, 2, 3]
console.log(msg1)//[empty × 6]

为了避免上面的问题,我们可以使用Array.of及逆行创建数组

let msg = Array.of(6)
console.log(msg.length)//1
console.log(msg)//[6]

4.类型的检测与转换

数组转换为字符串。

let array = [1,2,3,4]
console.log(array.toString())//1,2,3,4
console.log(String(array))//1,2,3,4
console.log(array.join("|"))//1|2|3|4

字符串转换为数组。

let str = "1234"
console.log(str.split(""))//["1", "2", "3", "4"]
console.log(Array.from(str))//这个方法还有第二个参数,用于操作每个一元素["1", "2", "3", "4"]
Array.from(str,function (item) {//循环对每一个对象进行操作
  console.log(item)//输出每一个字符
})

5.展开语法

使用点语法来代表多个参数。

let arr = ["weizhuren","erbihou"]
let msg = ["js","css"]
arr = [...arr,...msg]//点表达式相当于将数组的内容
console.log(arr)//["weizhuren", "erbihou", "js", "css"]

使用展开语法对不确定参数个数的方法进行传值。

  console.log(sum(2,3,5,6,7))//23
  function sum(...args) {
    let summation  = 0
    for(let i = 0;i < args.length;i++){
      summation += args[i]
    }
    return summation
  }

 展开语法可以用来复制一个新的数组,而不和原数组有同样的地址。

//使用展开语法
let array = [1,2,3,4]
let newArray = [...array]
newArray[newArray.length] = newArray.length
console.log(array) //[1, 2, 3, 4]
//不使用展开语法
let array = [1,2,3,4]
let newArray = array
newArray[newArray.length] = newArray.length
console.log(array) //[1, 2, 3, 4, 4]

6.解构语法

解构语法可以将数组中的值批量赋给变量。

let array = ["weizhuren",1995]
let [name,year] =array
console.log(name,year)//weizhuren 1995

结构语法与展开语法一起使用。

let [name,...msg] = ["weizhuren","erbihouke",1995]
console.log(name)//weizhuren
console.log(msg)// ["erbihouke", 1995]

定义结构语法默认值。

let [name,year=1995] = ["weizhuren"]
console.log(name,year)//weizhuren 1995

7.添加元素的多种操作技巧

JavaScript中可以使用多种方法对数组进行元素添加,如直接向数组内指定元素进行赋值、使用展开语法与结构语法一起对于数组进行赋值、以及使用JavaScript给我们提供的方法等。

值得一提的是,push方法可以直接改变数组本身,而不是返回一个新的数组,这个方法的返回值是增加元素后的数组长度。

let array = ["weizhuren","erbihou"]
array[array.length] = "js"//["weizhuren", "erbihou", "js"]
array = [...array,"css"]//["weizhuren", "erbihou", "css"]
array.push("html")//["weizhuren", "erbihou", "html"]

let arr1 = ["weizhuren","erbihouke"]
let arr2 = ["html","css","js"]
arr1.push(...arr2)//["weizhuren", "erbihouke", "html", "css", "js"]

8.数据出栈与入栈及填充操作

JavaScript提供了多种可以对数组进行操作的方法。这些方法都是可以直接改变数组本身的。

push方法可以向数组后面添加元素,返回值是添加元素后的数组长度,push方法可以一次插入多个元素。

//push方法
let array = ["weizhuren","erbihou"]
let length = array.push("html")
console.log(length)//3
console.log(array)//["weizhuren", "erbihou", "html"]

 pop方法可以删除数组中的最后一个元素,返回值是被删除的元素。

//pop方法
let arr = ["weizhuren","erbihou"]
let vars = arr.pop()
console.log(vars)//erbihou
console.log(arr)//["weizhuren"]

 unshift方法可以在数组最前面增加一个元素,返回值是增加元素后数组的个数,unshift方法可以一次插入多个元素。

//unshift方法
let array = ["weizhuren","erbihou"]
let length = array.unshift("魏主任")
console.log(vars)//3
console.log(array)//["魏主任", "weizhuren", "erbihou"]

 shift方法可以将数组最前面的一个元素删除,返回值是被删除的元素。

//shift方法
let array = ["weizhuren","erbihou"]
let vars = array.shift()
console.log(vars)//weizhuren
console.log(array)//["erbihou"]

fill方法可以对数组进行填充,在不指定填充位置和元素个数的时候,fill方法会将数组中所有的元素替换成我们给予的变量,fill方法的返回值是填充元素后的数组。

let array = ["weizhuren","erbihou"]
let vars = array.fill("魏主任")
console.log(array)//["魏主任", "魏主任"]
console.log(vars)//["魏主任", "魏主任"]

fill方法还可以对填充位置和填充数量进行限制,fill方法完整的参数是fill(“需要填充的变量”,从第几位开始填充,填充到第几位结束)。如果第三个参数小于第二个参数,fill方法不会改变数组。

let array = ["weizhuren","erbihou","html","css","js"]
let vars = array.fill("魏主任",2,4)//从第二个位置进行填充,填充到第四个位置
console.log(array)//["weizhuren", "erbihou", "魏主任", "魏主任", "js"]
console.log(vars)//["weizhuren", "erbihou", "魏主任", "魏主任", "js"]

9.splice与slice实现数组的增删改查

splice方法和slice方法可以对数组进行操作。

slice方法可以截取数组,但是并不会改变原数组的值。slice方法有两个参数,分别是从第几位开始截取,截取到第几位,slice(从第几位开始截取,截取到第几位);如果没有指定参数,返回的就是原数组;如果只给了第一个参数,就会返回从第一个参数位置向后产生的新数组。

let array = ["weizhuren","erbihou","html","css","js"]
let msg = array.slice(2,4)//从第二位开始截取,截取到第四位
console.log(array)//["weizhuren", "erbihou", "html", "css", "js"]
console.log(msg)//["html", "css"]

splice方法同样可以截取数组,但是会对原数组的值进行改变。splice方法同样也有两个基本参数,分别是从第几位开始截取,截取几位。splice方法的返回值是截取下来的数组。同样,在没有指定第二个参数的时候,splice方法会截取到数组最后。

let array = ["weizhuren","erbihou","html","css","js"]
let msg = array.splice(0,2)
console.log(array)//["html", "css", "js"]
console.log(msg)//["weizhuren", "erbihou"]

splice方法除了截取操作以外,还可以对数组进行替换操作,在两个基本参数之后传递变量,可以将变量插入到被截取的部分处。值得一提的是,如果插入的元素大于被截取长度的话,后面多余的元素依然会被插入到数组之中。

let array = ["weizhuren","erbihou","html","css","js"]
let msg = array.splice(1,1,"魏主任","李主任")
console.log(array)//["weizhuren", "魏主任","李主任","html", "css", "js"]
console.log(msg)//["erbihou"]

10.数组移动函数实例

使用splice方法实现数组内元素位置的替换。

function move(array,from,to) {
  if(from < 0 || to >= array.length){//判断参数是否符合移动标准
    console.error("参数错误")
    return
  }
  const newArray = [...array]//为了保证原数组不被改变,声明一个新的数组,并且使用点语法进行赋值,不会改变原数组的值
  let item = newArray.splice(from,1)//将需要改变位置的元素拿出来
  console.log(item)//[3]
  newArray.splice(to,0,...item)//将拿出来的元素放置到需要填充的位置
  return newArray
}
let array = [1,2,3,4]
console.log(move(array,2,3))//[1, 2, 4, 3]

11.清空数组的多种处理方式

清空一个数组有多种方法。

第一种,将数组赋空值。这种方法会将数组地址指向为空数组的地址,而不是改变了原地址中的数据。

let array = [1,2,3,4]
array = []
console.log(array)//[]

第二种,将数组长度设置为零。这种方法会将原地址中的数据清空,并不会产生新的内存地址。所以这种方法可以将数组彻底清除。

let array = [1,2,3,4]
array.length = 0
console.log(array)//[]

第三种,使用splice方法从第零位开始清除。

let array = [1,2,3,4]
array.splice(0)
console.log(array)//[]

第四种,使用pop方法循环删除元素。

let array = [1,2,3,4]
while(array.pop()){}
console.log(array)//[]

12.数组的拆分与合并操作

split方法可以将一个字符串拆分成数组;而jion方法可以将一个数组合并成一个字符串。

let str = "weizhuren,erbihouke"
let array = str.split(",")
console.log(array)//["weizhuren", "erbihouke"]
let newStr = array.join("-")
console.log(newStr)//weizhuren-erbihouke

concat方法可以连接两个数组。

let str = ["weizhuren","erbohou"]
let num = [1,2,3,4]
let newStr = str.concat(num)
console.log(newStr)//["weizhuren", "erbohou", 1, 2, 3, 4]

使用展开语法也可以连接两个数组。

let str = ["weizhuren","erbohou"]
let num = [1,2,3,4]
let newStr = [...str,...num]
console.log(newStr)//["weizhuren", "erbohou", 1, 2, 3, 4]

copyWithin方法可以复制数组中的元素。copyWithin方法有三个参数,分别是:从哪个位置开始插入;从哪个位置开始复制;复制.几位元素。

let str = [1,2,3,4,5,6,7]
let newStr = str.copyWithin(2,0,3)
console.log(newStr)//[1, 2, 1, 2, 3, 6, 7]

13.查找元素的基本使用

indexOf方法可以返回索引元素在数组中从左侧开始找到的第一个匹配元素的位置,如果不存在则返回-1。

let array = [1,2,3,4,1]
console.log(array.indexOf(1))//0
console.log(array.indexOf(9))//-1

lastIndexOf方法可以返回索引元素在数组中从右侧开始找到的第一个匹配元素的位置,如果不存在则返回-1。

let array = [1,2,3,4,1]
console.log(array.lastIndexOf(1))//4
console.log(array.lastIndexOf(9))//-1

值得一提的是,indexOf方法和lastIndexOf方法都存在第二个参数,用于标记从第几位开始进行查找,然而增加索引位置并不会改变原有元素返回的位置。

PS:lastIndexOf如果希望从最后n位开始查找,n的值应该是复数而不是正数。

let array = [1,2,3,4,1]
console.log(array.indexOf(1,1))//4
console.log(array.lastIndexOf(4,2))//-1

includes方法可以直接查询元素是否匹配,如果匹配则返回true,否则返回false。

let array = [1,2,3,4,1]
console.log(array.includes(1))//true
console.log(array.includes(9))//false

14.includes方法的实现原理

let array = [1,2,3,4,1]
function includes(arr,find) {
  for (const value of arr) if(value === find) return true //如果arr中有元素与find相等,即返回true
  return false//否则返回false
}
console.log(includes(array,3))//true
console.log(includes(array,99))//false

15.高效的find与findIndex新增方法

find方法可以遍历数组,并且返回符合条件的元素的值。如果不存在匹配的元素则返回undefined。

//可以找到符合条件的元素
let array = [1,2,3,4,5]
let res = array.find(function(item) {
  return item == 3
})
console.log(res)//3
//也可以找到符合条件的对象
let infoList = [
  {name:"weizhuren",age:"24"},
  {name:"yanglaoshi",age:"23"}
]
let info = infoList.find(function (item) {
  return item.name == "weizhuren"
})
console.log(info)//{name: "weizhuren", age: "24"}

findIndex方法与find方法相似,但是findIndex方法返回的是索引位置。

let array = [1,2,3,4,5]
let res = array.findIndex(function(item) {
  return item == 3
})
console.log(res)//2

let infoList = [
  {name:"weizhuren",age:"24"},
  {name:"yanglaoshi",age:"23"}
]
let info = infoList.findIndex(function (item) {
  return item.name == "weizhuren"
})
console.log(info)//0

16.自定义find原型方法实现

function find(arr,callback){
  for(const value of arr){
    if(callback(value)) return value
  }
  return undefined
}
let array = [1,2,3,4,5]
console.log(find(array,function (item) {
  return item == 2
}))//2

17.数组排序的使用技巧

使用sort方法可以将数组进行排序。sort方法会改变原数组,返回排序好的数组。

let array = [1,7,5,3,9]
array.sort(function (a,b) {
  return a - b //从小到大进行排列
})
console.log(array)//[1, 3, 5, 7, 9]

array.sort(function (a,b) {
  return a - b //从大到小进行排列
})
console.log(array)//[9, 7, 5, 3, 1]

18.sort排序算法的实现原理

let array = [1,7,5,3,9]
function sort(arr,callback) {
  for(const n in arr){
    for(const m in arr){
      if(callback(arr[n],arr[m]) < 0){
        const temp =  arr[n]
        arr[n] = arr[m]
        arr[m] = temp
      }
    }
  }
  return arr
}
array = sort(array,function (a,b) {
  return a - b
})
console.log(array)//[1, 3, 5, 7, 9]

19.循环操作中引用类型的使用技巧

for方法可以根据条件循环数组,for方法有三个参数,分别是:初始变量;循环条件;变量变化。

let lessons = [
  {title:"媒体查询相应式布局",category:"css"},
  {title:"flex弹性盒模型",category:"css"},
  {title:"MYSQL多表查询随意操作",category:"mysql"},
]
for(let i = 0;i<lessons.length;i++){
  lessons[i].title = `课程标题:${lessons[i].title}`;
}
console.log(lessons)
//{title: "课程标题:媒体查询相应式布局", category: "css"}
//1: {title: "课程标题:flex弹性盒模型", category: "css"}
//2: {title: "课程标题:MYSQL多表查询随意操作", category: "mysql"}

for of方法可以循环数组当中的每一个元素,并且取出数组元素的值。

for (const value of lessons) {
  value.title = `课程标题:${value.title}`
}
console.log(lessons)//打印结果同上

for in方法可以循环数组当中的每一个元素,并且取出数组元素的索引。

for (const key in lessons) {
  console.log(key) // 0 1 2
  lessons[key].title = `课程标题:${lessons[key].title}`
}
console.log(lessons)//打印结果同上

20.forEach循环方法的使用

forEach可以循环数组,并且返回元素,索引以及数组本身。

lessons.forEach(function (item,index,lessons) {
  console.log(item,index,lessons)//输出元素,索引以及数组本身
})

21.iterator迭代器方法玩转数组

数组的keys方法和values方法可以产生(?这个词不太好把握)迭代器,keys方法返回一个数组索引的迭代器,而values方法产生一个数组值的迭代器。迭代器的next方法可以返回两个值,分别是迭代器的值以及迭代是否完成,如果没有完成返回false,完成则返回true。

let array = ["weizhuren","erbihou"]
let keys = array.keys()//keys方法返回一个数组索引的迭代器
let values = array.values()//values方法返回一个数组值的迭代器
console.log(keys,values)//打印显示是两个iterator迭代器
let {value,done} = keys.next()//迭代器的next方法可以返回两个值,分别是:迭代器的值;迭代是否完成,如果没有完成返回false,完成则返回true
console.log(value,done)//"weizhuren",fasle

这里我们可以循环迭代器,检查返回的值是否正确。

while(({value,done} = values.next()) && done === false){
  console.log(value,done)
}
//weizhuren false
//erbihou false

迭代方法比较复杂,在这里不做过多的研究了,之后回对迭代器进行深入学习。

22.every与some这么用的

every方法可以遍历数组,并且可以取到数组的值,索引以及数组本身,当回调函数返回true时,回调函数会一直执行到遍历完数组的所有元素;当返回值为false或无返回值时,会结束遍历。在获取返回值时,每一次遍历都为真则为真,否则为假。

let array = ["weizhuren","erbihou"]
array.every(function (value,index,arr){//三个参数分别是元素值,索引,数组本身
  console.log(value,index)//weizhuren 0   erbihou 1
  console.log(arr)//["weizhuren", "erbihou"]
  return true
})

使用every方法判断是否所有人的成绩都及格。

const user = [
  {name:"李四",grade:63},
  {name:"王五",grade:55},
  {name:"赵六",grade:72},
]
const res = user.every(function (item){
  return item.grade >= 60
})
if(res){
  console.log(res?"所有同学全部及格":"有同学没有及格")//有同学没有及格
}

some方法与every方法相似,不同点在于some在获取返回值时,只要有一次判断为真,则返回值为真。

const res = user.some(function (item){
  return item.grade >= 60
})
if(res){
  console.log(res?"有同学及格了":"所有同学都没及格")//有同学及格了
}

23.filter过滤元素使用

filter方法可以遍历数组,它有三个参数,分别是:元素,索引,数组本身。filter方法有返回值且返回值是一个数组,如果返回真,则保留这个元素,如果返回假则舍弃这个元素,在遍历完整个数组后,返回符合条件的新数组。

let array = ["weizhuren","erbihou"]
let newArr = array.filter(function (value,index,arr) {
  return value.includes("wei")
})
console.log(newArr)//["weizhuren"]

使用filter方法过滤出css课程。

let lessons = [
  {title:"媒体查询相应式布局",category:"css"},
  {title:"FLEX弹性盒模型",category:"css"},
  {title:"MYSQL多表查询随意操作",category:"mysql"},
]
let cssLessons = lessons.filter(function (value){
  return value.category == "css"
})
console.log(cssLessons)
// {title: "媒体查询相应式布局", category: "css"}
// {title: "FLEX弹性盒模型", category: "css"}

24.自定义过滤函数理解原理

let array = [1,2,3,4]
//自定义filer方法,有两个参数:原数组,需要过滤的参数
function filter(array,except){
  //定义一个新数组保存过滤后的参数
  let newArr = []
  //循环原数组
  for(const value of array){
  //判断需要过滤的参数是否和原数组参数相同,如果不相同则push到存放元素的新数组中
    if(except.includes(value) == false){
      newArr.push(value)
    }
  }
  return newArr
}
console.log(filter(array,[2,3]))//[1, 4]

25.map映射数组与引用类型处理技巧

map数组映射方法可以理解为复印一份数组,在复印过程中我们可以对数组进行二次处理。map方法同样有个三参数,分别是元素值,索引值以及数组本身。map方法的返回值返回什么,那么新数组就是什么,并且map方法不会改变值类型原数组,但是会改变引用类型原数组。

let array = ["weizhuren","erbihou"]
let newArr = array.map(function (value,item,arr){
  return 2
})
console.log(newArr)//[2, 2]

使用map方法修改课程名称。

let lessons = [
  {title:"媒体查询相应式布局",category:"css"},
  {title:"FLEX弹性盒模型",category:"css"},
  {title:"MYSQL多表查询随意操作",category:"mysql"},
]
let newArr = lessons.map(function (value,item,arr){
  value = `课程:${value.title}`
  return value
})
console.log(newArr)
//0: "课程:媒体查询相应式布局"
//1: "课程:FLEX弹性盒模型"
//2: "课程:MYSQL多表查询随意操作"

使用map方法给原数组引用类型添加属性。

lessons.map(function (value,item,arr){
  value.click = 100
})
console.log(lessons)
//{title: "媒体查询相应式布局", category: "css", click: 100}
// {title: "FLEX弹性盒模型", category: "css", click: 100}
// {title: "MYSQL多表查询随意操作", category: "mysql", click: 100}

也可以使用浅拷贝Object.assign方法,不改变原数组,这部分在学习对象的时候在进行详细说明。

26.超好用的reduce方法

reduce方法可以遍历一个数组,它的第一个参数是一个方法,方法中有四个参数,分别是:上一次循环的返回值(第一次的时候这个值为数组的第一个元素,如果没有返回值这个值为undefined),当前元素的值(这个值从第二个元素开始),索引值(这个值从第二个元素开始),数组本身。

let array = [1,2,3,4,5]
array.reduce(function (pre,value,index,arr){
  console.log(pre,value,index)
  return `返回值为${value * 2}`
})
// 1 2 1
// 返回值为4 3 2
// 返回值为6 4 3
// 返回值为8 5 4

并且reduce方法可以有第二个参数,第二个参数可以定义第一个参数(方法)中的第一个参数(第一次的返回值)。给了这个参数以后,ruduce方法就从数组的第一位开始遍历了。

let array = [1,2,3,4,5]
array.reduce(function (pre,value,index,arr){
  console.log(pre,value,index)
  return `返回值为${value * 2}`
},100)
//100 1 0
// 返回值为2 2 1
// 返回值为4 3 2
// 返回值为6 4 3
// 返回值为8 5 4

使用reduce方法统计数组中某个元素出现的次数。

let array = [1,2,1,4,1]
//定义一个统计次数的方法,传递两个参数:数组本身以及统计元素
function arrayCount(arr,item){
//使用reduce方法,并且给返回值设置初始值0,当需要统计的元素与数组遍历到的元素相等时,这个值加一
  return arr.reduce(function(total,cur){
    total += item == cur ? 1: 0
    return total
  },0)
}
console.log(arrayCount(array,1))

使用reduce方法找出数组中最大的数。

let array = [1,2,7,4,3]
//定义一个统计数组中最大元素的方法,传入一个参数:原数组
function arrayMax(arr){
//使用reduce方法,判断返回值与当前索引值的大小,如果返回值大于等于索引值则返回返回值,否则返回索引值
  return arr.reduce(function(pre,value){
    return pre >= value ? pre : value
  })
}
console.log(arrayMax(array))//7

27.购物车汇总与获取最贵商品

let cart = [
  {name:"iphone",price:12000},
  {name:"ipad",price:3200},
  {name:"macBook",price:15000},
]
//获得购物车里最贵的商品,判断前一个商品的价格是否比当前商品价格高或相等,如果符合条件返回前一个商品,否则返回当前商品
let maxPrice = cart.reduce(function (pre,value){
  return pre.price >= value.price ? pre : value
})
//计算购物车里所有商品的总价,把返回值的默认值设置为0,当遍历数组时,将当前商品价格加到返回值上
let allPrice = cart.reduce(function (pre,value){
  pre += value.price
  return pre
},0)
console.log(maxPrice,allPrice)//{name: "macBook", price: 15000} 30200

28.获取购物车中价格超过一万元的商品的名称

//定义一个方法,传递两个参数:原数组与比较的价格
//获取购物车中价格超过一万元的商品的名称
function getNamebyPrice(arr,price){
  return arr.reduce(function(pre,value){
    if(value.price >= price) pre.push(value)
    return pre
  },[]).map(res =>{//箭头函数,在之后函数部分详细说明
    return res.name
  })
}
console.log(getNamebyPrice(cart,10000))//["iphone", "macBook"]

29.处理购物车中重复商品

function filterGoods(arr){
//使用reduce方法遍历数组,并且将返回值的初始值设为空数组[]
  return arr.reduce(function(pre,value){
//使用find方法判断返回值里是否有与当前值相同的元素
    let find = pre.find(function(v){
      return v.name == value.name
    })
//如果存在不相同的元素,则将value元素push到返回值中
    if(!find) pre.push(value)
    return pre
  },[])
}
console.log(filterGoods(cart))
// {name: "macBook", price: 15000}
// {name: "iphone", price: 12000}
// {name: "ipad", price: 3200}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!