# 操作数据

  原数组的元素是个对象引用,被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。

  所以我们在使用数组迭代的时候要格外注意:

let arr = [
  { id: 1, name: '西瓜', status: true, price: 10, count: 2 },
  { id: 2, name: '榴莲', status: false, price: 80, count: 1 },
  { id: 3, name: '草莓', status: true, price: 20, count: 3 }
]

let newArr = arr.map((item) => {
  // item.name === '草莓'? item.price-- : item

  // 没有修改原数组
  item.name === '草莓' ? { ...arr, price: item.price - 1 } : item
})

# 跳出循环

  • break:跳出循环,终止循环
  • continue:跳过本次循环,继续下一次循环
  • return:终止函数,返回值
let arr = ['苹果', '香蕉', '草莓', '橘子', '葡萄', '柚子']

for (let i = 0; i < arr.length; i++) {
  if (arr[i] === '草莓') {
    break
  }
  console.log(arr[i]) // 输出:'苹果', '香蕉'
}

for (let i = 0; i < arr.length; i++) {
  if (arr[i] === '草莓') {
    continue
  }
  console.log(arr[i]) // 输出:'苹果', '香蕉', '橘子', '葡萄', '柚子'
}

function test() {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === '草莓') {
      return i
    }
  }
}
console.log(test()) // 输出:3

# 一、forEach() -- 循环

arr.forEach(callback(currentValue [, index [, array]])[, thisArg])

TIP

forEach 方法传入的是一个 回调函数,没有返回值

描述:

  对当前数组的每个元素执行一次给定的函数(类似:for遍历数组 )

特性:

  • 除了抛出异常以外,无法中止或跳出 forEach() 循环

  • 也可使用于 Array、Map、Set、URLSearchParams 等等

# 1、代码示例

const arr = ['我', '你', '它', '他', '她']

// 回调函数(自动🤔调用)
arr.forEach((item, index, arr) => {
  // arr参数表示原数组,可以在需要的时候使用
  console.log(item, index)
})

# 2、应用场景

  • for 循环转换
const items = ['item1', 'item2', 'item3']
const copy = []

// before
for (let i = 0; i < items.length; i++) {
  copy.push(items[i])
}

// after
items.forEach(function (item) {
  copy.push(item)
})

# 二、map() -- 映射 ✨

var new_array = arr.map(function callback(currentValue[, index[, array]]) {
 // Return element for new_array
}[, thisArg])

TIP

map 方法和 forEach 方法类似,不同的是 map 方法映射了一个新的数组,并 return 该数组的每一个元素

描述:

  创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。

# 1、代码示例

const arr = ['我', '你', '它', '他', '她']

// 回调函数(自动🤔调用)
const arr2 = arr.map((item, index, arr) => {
  // arr参数表示原数组,可以在需要的时候使用
  console.log(item, index)

  return item
})

# 2、应用场景

  • forEach 循环转换
const items = ['item1', 'item2', 'item3']
const copy1 = []

// before
items.forEach(function (item) {
  copy1.push(item)
})

// after
const copy2 = items.map(function (item) {
  return item
})
  • ASCII 码获取 🤔
var map = Array.prototype.map
var a = map.call('Hello World', function (item) {
  return item.charCodeAt(0)
})
// a 的值为 [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

# 三、filter() -- 过滤

var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

TIP

filter 方法和 map 方法类似,不同的是 filter 方法 return 的是 Boolean 值(即满足条件就才加入新数组)

描述:

  对所有数组元素进行检测、查找 。返回是一个通过测试 新数组

# 1、代码示例

// filter()方法示例:筛选符合条件的元素
const numbers = [1, 2, 3, 4, 5]

// 筛选出数组中的偶数
const evenNumbers = numbers.filter(function (number) {
  // arr参数表示原数组,可以在需要的时候使用
  return number % 2 === 0
})

console.log(evenNumbers) // 输出:[2, 4]

# 2、应用场景:

对购物车选中的商品价格累加

const arr = [
  { id: 1, name: '西瓜', status: true, price: 10, count: 2 },
  { id: 2, name: '榴莲', status: false, price: 80, count: 1 },
  { id: 3, name: '草莓', status: true, price: 20, count: 3 }
]

// 一般使用
// const arrNew = arr.filter(item => item.status)

// 高级使用:多作为辅助🍗方法
let priceAll = 0
const arr2 = arr
  .filter((item) => item.status)
  .forEach((item) => {
    priceAll += item.price * item.count
  })

console.log(priceAll)

# 四、every() -- 结果

arr.some(callback(element[, index[, array]])[, thisArg])

TIP

every 方法和 filter 方法类似,不同的是 every 方法 要的只是个结果,得到的是一个 Boolean 值;而前者要的是一个满足条件的新数组

描述:

  测试(查找)一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值

特性:

  • 若收到一个空数组,此方法在任何情况下都会返回 true。

# 1、代码示例

const arr = ['我', '你', '它', '他', '她']

// 回调函数(自动🤔调用)
const result = arr.every((item, index, arr) => {
  // arr参数表示原数组,可以在需要的时候使用
  console.log(item, index)

  return true
})

# 2、应用场景:

判断是否全选

const arr = [
  { id: 1, name: '华为', status: true },
  { id: 2, name: '小米', status: false },
  { id: 3, name: '格力', status: true }
]

// 它的返回值✨是一个Boolean值
const result = arr.every((item) => {
  // 检测是不是所有的status值都为true
  return item.status === true
})

console.log(result)

// 简写
// const result = arr.every(item => item.status)

结果:

false

# 五、some() -- 结果

arr.some(callback(element[, index[, array]])[, thisArg])

TIP

some 方法和 every 方法类似,不同的是 some 方法 筛选时,只要有一个满足条件就立即停止,并返回 true 结果。

描述:

  测试(查找)数组中是不是至少有 1 个元素通过了被提供的函数测试。它 返回的是一个 Boolean 类型的值

特性:

  • 如果用一个空数组进行测试,在任何情况下它返回的都是 false。

# 1、代码示例

// some()方法示例:判断数组中是否存在满足某个条件的元素
const names = ['Alice', 'Bob', 'Charlie', 'Dave']

// 检查数组中是否存在名字以'B'开头的元素
const hasNameStartingWithB = names.some(function (name) {
  return name.startsWith('B')
})

console.log(hasNameStartingWithB) // true

# 2、应用场景

思考

  从这里来讲,some()又像是一个加强版的 includes()方法

  • includes 方法 封装
var fruits = ['apple', 'banana', 'mango', 'guava']

function includes(arr, val) {
  // 侧重点:✨some()方法的返回值
  return arr.some(function (arrVal) {
    return val === arrVal
  })
  // 简写
  // return arr.some(arrVal => val === arrVal);
}

includes(fruits, 'kela') // false
includes(fruits, 'banana') // true

# 3、find() 方法 🚩

  ES6 中,新增加了一个 find() 方法,用于找出第一个符合条件的数组成员 item。

  • 该方法返回的是第一个符合条件的元素
  • 如果没找到,则返回 undefined。

  若想返回其他内容:

  • findIndex(): 返回索引

array.find(callback(value, index, arr), thisValue);

let arr = [1, 3, 4, 5]
let result = arr.find(function (value) {
  return value > 2
})
console.log(result) // 3

思考

  除了 forEach()方法外,其他数组迭代方法都需要 return

  并且由于 map()方法 和 filter 方法 返回的是一个数组,所以还可以对返回后的数组进行进一步操作

对比 ✍
  • filter()方法
var arr = [1, 2, 3, 4, 5]

var result = arr.filter(function (item) {
  return item > 2
})
console.log(result) // [3, 4, 5]
  • every() 方法
var arr = [1, 2, 3, 4, 5]

var result = arr.every(function (item) {
  return item > 2
})
console.log(result) // false
  • some() 方式
var arr = [1, 2, 3, 4, 5]

var result = arr.some(function (item) {
  return item > 2
})
console.log(result) // true

# 六、reduce() 叠加 ✨

  对数组内的每一项进行叠加处理:可加、可乘、可字符串等等

arr.reduce(function (previousValue, currentValue, currentIndex, array) {
  /* … */
}, initialValue)

提示

这里的 prev,可以想象成是 上一次的 total 值

# 1、代码示例

var arr = [1, 2, 3, 4, 5, 6]

var total = arr.reduce(function (prev, item) {
  return (prev += item)
}, 0) // prev初始值设置为 0

console.log(total) // 21

# 2、应用场景:

对购物车选中的商品价格累加

const arr = [
  { id: 1, name: '西瓜', status: true, price: 10, count: 2 },
  { id: 2, name: '榴莲', status: false, price: 80, count: 1 },
  { id: 3, name: '草莓', status: true, price: 20, count: 3 }
]

// 可进一步简写为:
// const result = arr.filter(item => item.status).reduce((priceAll, item) =>  priceAll += (item.price * item.count), 0)

/* 方式二 */
// 结构:arr.filter(item => item.status).reduce((总值, item) => {},初始值)
const result = arr
  .filter((item) => item.status)
  .reduce((priceAll, item) => {
    return (priceAll += item.price * item.count)
  }, 0)

console.log(result)

对数组元素进行去重

let arr = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd']

let result = arr.reduce(function (prev, item) {
  if (prev.indexOf(item) === -1) {
    prev.push(item)
  }

  return prev
}, [])

console.log(result) // ['a', 'b', 'c', 'e', 'd']

统计数组中某个元素出现的次数

let arr = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']

const result = arr.reduce(function (prev, item) {
  // if (item in prev) {
  //   prev[item]++
  // } else {
  //   prev[item] = 1
  // }

  // ✍
  prev[item] = prev[item] + 1 || 1

  return prev
}, {})

console.log(result) // {Alice: 2,Bob: 1,Bruce: 1,Tiff: 1}

# 3、更多

对二维数组进行偏平化处理

var arr = [
  [0, 1],
  [2, 3],
  [4, 5]
]
let result = arr.reduce(function (prev, item) {
  return prev.concat(item)
}, [])

console.log(result) // [0, 1, 2, 3, 4, 5]
更新于 : 7/8/2024, 10:21:14 AM