常用的 JS 陣列方法

Array.prototype.forEach()

  • 將陣列內元素一個一個抓出來帶入 function 執行
  • 只能用在陣列上
  • 沒有回傳值(回傳 undefined)
  • 無法中斷 (無法 return 或 break)
  • 適合沒有改動資料,只是想用陣列中的資料做點事的情況

語法

array.forEach(function(currentValue, index, arr), thisValue)

//currentValue: 目前被處理中Array之中的元素 (必填)
//index: 目前被處理中Array之中元素的index (選填)
//arr:呼叫 forEach() 方法的那個 Array 本身(選填)
//thisValue: 執行 callback 回呼函式的 this(即參考之 Object)值 (選填)

範例

  • 男女人數計算
data = [
  { name: 'Jay', gender: 'male' },
  { name: 'Mary', gender: 'female' },
  { name: 'Max', gender: 'male' }
]

let people = { male: 0, female: 0 }

data.forEach(function (item, index) {
  if (item.gender === 'male') {
    people.male += 1
  } else {
    people.female += 1
  }
})

console.log(people) // { male:2, female:1 }
  • 是否改變原陣列
//不會改變原陣列
const arr = [1, 2, 3, 4, 5]
arr.forEach((num) => (num *= 2))
console.log(arr) // [1,2,3,4,5]

//會改變原陣列
arr.forEach((num, index) => (arr[index] *= 2))
console.log(arr) // [2,4,6,8,10]
  • 把陣列的值取出來另存
//篩選大於2的數字,存入新陣列
const arr = [1, 2, 3, 4, 5]
let newArr = []
arr.forEach((num) => {
  if (num > 2) {
    newArr.push(num)
  }
})
console.log(newArr) // [3,4,5]
  • 處理類陣列
//類陣列無法使用陣列方法
const elements = document.querySelectorAll('p') // 取得所有 <p> 元素
const elementArray = Array.from(elements) // 將 NodeList 轉換為陣列

elementArray.forEach(function (element) {
  element.innerText = 'created by forEach'
})

Array.prototype.map()

  • 遍歷原陣列,將每個元素拿出來運算,再把運算後的結果放入新陣列
  • 會回傳一個新陣列,不會改變原陣列
  • 適合用在需要改動資料的時候。將原始的變數運算後重新組合一個新的陣列

語法

array.map(function(currentValue, index, arr), thisValue)

範例

  • 把陣列中的數字乘以 2
const arr = [1, 2, 3, 4, 5, 6]
const arr2 = arr.map((num) => num * 2)

//回傳一個新陣列
console.log(arr2) // [2, 4, 6, 8, 10, 12];
  • 檢查是否大於 1
//回傳的是運算後的結果
const arr = [1, 2, 3, 4]
const newarr = arr.map(function (item) {
  return item > 1
})
console.log(newarr) // [false,true,true,true]

//跟filter的差別,如果是true會回傳該元素
const arr = [1, 2, 3, 4]
const newarr = arr.filter(function (item) {
  return item > 1
})
console.log(newarr) // [2,3,4]
  • 兩個陣列組合
const items = ['book', 'cap', 'bag']
const prices = [125, 76, 390]

const listItems = items.map((elem, index) => ({ itemName: elem, price: prices[index] }))

console.log(listItems)
;[
  {
    itemName: 'book',
    price: 125
  },
  {
    itemName: 'cap',
    price: 76
  },
  {
    itemName: 'bag',
    price: 390
  }
]

Array.prototype.filter()

  • 遍歷原陣列,根據回傳值(true/false)決定要不要把元素複製到新陣列
  • 如果運算結果是 true,把元素放到新陣列
  • 會回傳一個新陣列,不會改變原陣列
  • 如果陣列中都沒有符合的值,回傳空陣列

語法

array.filter(function(currentValue, index, arr), thisValue)

範例

  • 篩選陣列中所有偶數
const numbers = [1, 2, 3, 4, 5]
const evenNumbers = numbers.filter((num) => num % 2 === 0)
console.log(evenNumbers) // [2, 4]
  • 篩選符合條件的物件
const persons = [
  { name: 'Alice', age: 22 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 28 },
  { name: 'David', age: 35 }
]

const youngPersons = persons.filter(function (person) {
  return person.age < 30
})

console.log(youngPersons)
// [
//   { name: 'Alice', age: 22 },
//   { name: 'Charlie', age: 28 },
// ]
  • 簡易搜尋資料
// example1:
// 篩選名字包含'電'字的資料
const arr = [
  {
    name: '電視',
    price: 20
  },
  {
    name: '電腦',
    price: 15
  },
  {
    name: '相機',
    price: 10
  }
]

const newarr = arr.filter((item) => {
  return item.name.match('電')
})
console.log(newarr)
//[ {name:"電視",price: 20},{ name:"電腦",price: 15} ]

// example2:
// 依輸入名稱搜尋
const searchInput = document.querySelector('.search_input')
const searchOrder = (orders) => {
  if (searchInput.value.trim() === '') {
    alert('請先輸入內容')
    return
  }
  const filteredData = orders.filter((item) => {
    return item.clientName.match(searchInput.value.trim())
  })
  searchInput.value = ''
  render(filteredData)
}

Array.prototype.sort()

  • 預設會將元素轉型成 字串 再做比較
  • 比較的方式是從左到右逐一比對元素中的每個字元的 Unicode code point 大小
  • 執行後會回傳排序後的陣列
  • 會改變原陣列排序

語法 1-預設排序

arr.sort()

範例-直接使用.sort( )排列

//字串排序
const fruits = ['cherries', 'apples', 'bananas']

console.log(fruits.sort()) //  ["apples", "bananas", "cherries"]
console.log(fruits) // ["apples", "bananas", "cherries"]

//數字排序
const numbers = [3, 200, 120, 20]

console.log(numbers.sort()) // [120, 20, 200, 3]
// 把數字轉成字串比較
// 會根據字串第一個字元的 Unicode編碼從小到大排序
// 回傳排序後的陣列

語法 2-傳入一個比較函式

arr.sort([compareFunction])
  • 指定一個函式來定義排序順序
  • 當使用比較函式時,數字會被正確的排序,不管是數字還是數字字串
  • 假如省略此參數,陣列將根據各個元素轉為字串後的每一個字元之 Unicode 編碼位置值進行排序
    compareFn(a , b) return valuesort order
    > 0b comes first
    < 0a comes first
    === 0Keep original order of a and b

範例-數字比較排序

//純數字排序
const numbers = [3, 200, 120, 20]

console.log(
  numbers.sort((a, b) => {
    return a - b
  })
)
// 3 跟 200 比較, 3 - 200 會 < 0
// 3 排在200的前面...

// [3, 20, 120, 200]

//數字和字串排序
//沒有轉型成數字還是可以正確排序的原因:
//在JS中使用 '-' 時,會被轉型成數字類型比較
const scores = ['900', 66, 878787, '1103']

console.log(
  scores.sort((a, b) => {
    return a - b
  })
) // [66, '900', '1103', 878787]

範例-更改排序的條件

// return a - b 升序排序
const numbers = [4, 2, 5, 1, 3]
numbers.sort(function (a, b) {
  return a - b
})
console.log(numbers) // [1, 2, 3, 4, 5] 從小到大

// return b - a 降序排序
const numbers = [4, 2, 5, 1, 3]
numbers.sort(function (a, b) {
  return b - a
})
// 4 跟 2 比較, 2-4 會 < 0
// 4排在2的前面...

console.log(numbers) // [5, 4 ,3 ,2 ,1 ] 從大到小

//依照物件當中屬性的值排序
const people = [
  { name: 'Ken', age: 18 },
  { name: 'Mark', age: 30 },
  { name: 'Sam', age: 26 },
  { name: 'Roy', age: 13 }
]

//依照年齡遞增排序
people.sort((a, b) => {
  return a.age - b.age
})

console.log(people)
//[
//{ name: 'Roy', age: 13 },
//{ name: 'Ken', age: 18 },
//{ name: 'Sam', age: 26 },
//{ name: 'Mark', age: 30 }
//]

//依照年齡遞減排序
people.sort((a, b) => {
  return b.age - a.age
})

console.log(people)
//[
//{ name: 'Mark', age: 30 },
//{ name: 'Sam', age: 26 },
//{ name: 'Ken', age: 18 },
//{ name: 'Roy', age: 13 }
//]

Array.prototype.reduce()

  • 用來對陣列進行迭代並將所有元素縮減成單一值

步驟:

  1. 定義一個陣列
  2. 呼叫 reduce() 方法,並傳入 callback function 和可選的初始值
  3. callback function 會被遞歸呼叫,對每個陣列元素進行處理並返回累積的值
  4. 回傳最後一次執行 callback function 後得到的值

語法

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

//total:每次陣列迭代時所記錄的結果(必填)

//currentValue:目前陣列所迭代的元素(必填)

//currentIndex:目前陣列所迭代的元素index(選填)

//arr:迭代的陣列對象(選填)

//initialValue:初始值(選填)
//如果未提供初始值,則使用陣列的第一個元素作為初始值,並從第二個元素開始處理

範例

  • 加總陣列的值
//初始值預設為0
const arr = [1, 2, 3, 4, 5]
const result = arr.reduce((acc, cur) => acc + cur, 0)
console.log(result) // 15

//沒有提供初始值,會取陣列中的第一個元素 1 當作初始值
//currentValue從陣列的第二個元素開始遍歷

const sum = arr.reduce((acc, cur) => acc + cur)
console.log(sum) // 15
  • 加總物件屬性的值
const items = [
  { name: 'water', price: 20 },
  { name: 'cookie', price: 40 },
  { name: 'riceball', price: 60 },
  { name: 'coffee', price: 80 }
]
const totalPrice = items.reduce((total, item) => {
  return total + item.price
}, 0)

console.log(totalPrice) // 200
  • 將陣列中的字串連接
const words = ['hello', 'world', 'how', 'are', 'you']
const sentence = words.reduce((accumulator, currentValue) => {
  return accumulator + ' ' + currentValue
}, '')

//回傳字串
console.log(sentence) // "hello world how are you"
  • 組合陣列
//寫法1
const nestedArray = [
  [1, 2],
  [3, 4],
  [5, 6]
]
const flattenedArray = nestedArray.reduce((accumulator, currentValue) => {
  return accumulator.concat(currentValue)
}, [])
console.log(flattenedArray) // [1, 2, 3, 4, 5, 6]

//寫法2
const newArr = nestedArray.reduce((acc, cur) => [...acc, ...cur], [])
console.log(newArr) //  [1, 2, 3, 4, 5, 6]
  • 按條件篩選陣列中的元素
const people = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 20 },
  { name: 'David', age: 35 }
]
const filteredPeople = people.reduce((accumulator, currentValue) => {
  if (currentValue.age >= 30) {
    accumulator.push(currentValue.name)
  }
  return accumulator
}, [])

//回傳陣列
console.log(filteredPeople) // ["Bob", "David"]

Array.prototype.some()

  • 檢查是否至少有一個陣列元素符合條件,回傳 boolean
  • 只要有一個條件符合,就停止遍歷並回傳 true
  • 全部都不符合回傳 false

語法

array.some(function(value, index, arr), this)

範例

  • 確認是否有偶數
const numbers = [1, 2, 3, 4, 5]
const isEven = (number) => number % 2 === 0

const hasEvenNumber = numbers.some(isEven)
console.log(hasEvenNumber) // true

Array.prototype.every()

  • 檢查是否所有陣列元素都符合條件,回傳 boolean
  • 如果全部都符合回傳 true,只要有一個不符合就停止遍歷,回傳 false

語法

array.every(function(currentValue, index, arr), thisValue)

範例

  • 是否大於 10
function isBigEnough(element, index, array) {
  return element >= 10
}
;[12, 5, 8, 130, 44].every(isBigEnough) // false
;[12, 54, 18, 130, 44].every(isBigEnough) // true

參考資料

# JavaScript # Array