🧭 JavaScript 数组方法应用实例
# split()  /  join()
 # 转换短划线命名为驼峰命名
编写函数
camelize(str)。即:删除所有短横线,并将短横线后的每一个单词的首字母变为大写。例如my-short-string转换为myShortString。
相关用例:
camelize("background-color") == 'backgroundColor';
camelize("list-style-image") == 'listStyleImage';
camelize("-webkit-transition") == 'WebkitTransition';
 2
3
点击查看
function camelize(str) {
    return str.split('-').map((item, index)=> index === 0 ? item : item[0].toUpperCase() + item.slice(1)).join('')
}
 2
3
涉及关键字  split  /  map  /  toUpperCase  /  join
# 拓展的 Calculator
实现两部分功能:
现
calculate(str)方法,该方法接受像"1 + 2"这样格式为 “数字 运算符 数字”(以空格分隔)的字符串,并返回结果。该方法需要能够理解加号+和减号-。let calc = new Calculator; console.log( calc.calculate("3 + 7") );1
2添加方法
addMethod(name, func),该方法教 calculator 进行新操作。它需要运算符name和实现它的双参数函数func(a,b)。let powerCalc = new Calculator; powerCalc.addMethod("*", (a, b) => a * b); powerCalc.addMethod("/", (a, b) => a / b); powerCalc.addMethod("**", (a, b) => a ** b); let result = powerCalc.calculate("2 ** 3"); console.log(result); // 81
2
3
4
5
6
7
点击查看
  function Calculator() {
    this.methods = {
      '+': (a ,b) => a + b,
      '-': (a, b) => a - b
    }
    this.calculate = function(str) {
      let arr = str.split(' ')
      let a = +arr[0]
      let operator = arr[1]
      let b = +arr[2]
      if(!this.methods[operator] || isNaN(a) || isNaN(b)) {
        return NaN
      }
      return this.methods[operator](a, b)
    }
    this.addMethod = function(name, func) {
      this.methods[name] = func
    }
  }
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
关键词:对象方法 |  split
# filter()
 # 过滤范围
写一个函数
filterRange(arr, a, b),该函数获取一个数组arr,在其中查找数值大于或等于a,且小于或等于b的元素,并将结果以数组的形式返回。该函数不应该修改原数组。它应该返回新的数组。
相关用例:
let arr = [5, 3, 8, 1];
let filtered = filterRange(arr, 1, 4);
alert( filtered ); // 3,1(匹配值)
alert( arr ); // 5,3,8,1(未修改)
 2
3
4
点击查看
function filterRange(arr, a, b) {
    return arr.filter((item) => item >= a && item <= b)
  }
 2
3
# 原位过滤范围
与上一题类似,在原数组中,过滤(删除)不在  [a, b]  范围内的元素。该函数应该只修改数组。它不应该返回任何东西。
相关用例:
let arr = [5, 3, 8, 1];
filterRangeInPlace(arr, 1, 4); // 删除了范围在 1 到 4 之外的所有值
alert( arr ); // [3, 1]
 2
3
点击查看
function filterRangeInPlace(arr, a, b) {
  for (let i = 0; i < arr.length; i++) {
    let val = arr[i];
    // 如果超出范围,则删除
    if (val < a || val > b) {
      arr.splice(i, 1);
      i--;
    }
  }
}
 2
3
4
5
6
7
8
9
10
11
12
13
# map()  映射
 # 映射到  names
 
user对象数组,每个对象都有user.name,将其转换为names数组的代码。
let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 28 };
let users = [ john, pete, mary ];
let names = /* ... your code */
console.log(names); // John, Pete, Mary
 2
3
4
5
6
7
8
点击查看
let names = users.map((user) => user.name)
 # 映射到对象
以数组
users为基础,创建另一个具有id和fullName的对象数组,其中fullName由name和surname生成。
let john = { name: "John", surname: "Smith", id: 1 };
let pete = { name: "Pete", surname: "Hunt", id: 2 };
let mary = { name: "Mary", surname: "Key", id: 3 };
let users = [ john, pete, mary ];
let usersMapped = /* ... your code ... */
/*
usersMapped = [
  { fullName: "John Smith", id: 1 },
  { fullName: "Pete Hunt", id: 2 },
  { fullName: "Mary Key", id: 3 }
]
*/
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
点击查看
let usersMapped = users.map((user) => ({
  fullName: `${user.name} ${user.surname}`,
  id: user.id
}))
 2
3
4
注意
注意,在箭头函数中,返回一个对象需要使用额外的括号。如果只写一个  {}  ,JavaScript 在这里会把  {  视为函数体的开始,而不是对象的开始。解决方法是将它们包装在普通括号  ()  中。
# sort()  数组排序
 # 根据对象中的数据排序
编写函数
sortByAge(users)获得对象数组的age属性,并根据age对这些对象数组进行排序。
let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 28 };
let arr = [ pete, john, mary ];
sortByAge(arr);
 2
3
4
5
6
7
点击查看
function sortByAge(arr) {
  arr.sort((a, b) => a.age - b.age)
}
 2
3
# 随机排序
编写函数
shuffle(array)将let arr = [1, 2, 3];随机排序。所有元素顺序应该具有相等的概率。例如,可以将[1,2,3]重新排序为[1,2,3]或[1,3,2]或[3,1,2]等,每种情况的概率相等。
点击查看
思路:使用  Math.random()  生成一个 可能是正数或者负数的 随机数,这样  sort()  才能随机对数组中的元素重新排序。
简单的使用  Math.random() - 0.5  ,但是这个方法得出所有的排列的概率不相同。
function shuffle(array) {
  array.sort((a, b) => (Math.random() - 0.5))
}
 2
3
能实现的一个算法「Fisher-Yates shuffle (opens new window)」,逆向遍历数组,并将每个元素与前面的随机的一个元素互换位置。能实现得出所有排列都以相同的概率出现,并且不需排序增加时间开销。
function shuffle(array) {
  for(let i = array.length - 1; i > 0; i--) {
    let j = Math.floor(Math.random() * (i + 1))
    
    // 一般交换
    let temp = array[i]
    array[i] = array[j]
    array[j] = array[i]
  }
}
 2
3
4
5
6
7
8
9
10
使用解构分配交换:
[array[i], array[j]] = [array[j], array[i]]1
关键字:  Math.random()  |  sort()
# reduce()
 # 计算平均值
编写
getAverageAge(users)函数,该函数获取一个具有age属性的对象数组,并返回平均年龄。
let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 29 };
let arr = [ john, pete, mary ];
alert( getAverageAge(arr) );
 2
3
4
5
6
7
点击查看
function getAverageAge(arr) {
  return arr.reduce((sum, item) => sum + item.age, 0) / arr.length
}
 2
3
# 从数组创建对象
假设收到了一个用户数组,形式为:
{id:..., name:..., age:... }。创建一个函数
groupById(arr)从该数组创建对象,以id为键(key),数组项为值。
let users = [
  {id: 'john', name: "John Smith", age: 20},
  {id: 'ann', name: "Ann Smith", age: 24},
  {id: 'pete', name: "Pete Peterson", age: 31},
];
let usersById = groupById(users);
// after: 
/* 
usersById = {
  john: {id: 'john', name: "John Smith", age: 20},
  ann: {id: 'ann', name: "Ann Smith", age: 24},
  pete: {id: 'pete', name: "Pete Peterson", age: 31},
}
*/
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
点击查看
function groupById(array) {
    return array.reduce((obj, item)=>{
      obj[item.id] = item
      return obj
    },{})
  }
 2
3
4
5
6
注意要将累加器的初始值设置为
{}
# includes()
 # 数组去重
创建一个函数
unique(arr),返回去除重复元素后的数组arr。
function unique(arr) {
  /* your code */
}
let strings = ["Hare", "Krishna", "Hare", "Krishna",
  "Krishna", "Krishna", "Hare", "Hare", ":-O"
];
 2
3
4
5
6
7
点击查看
function unique(arr){
  let res = []
  
  for (let item of arr) {
    if(!res.includes(item)){
      res.push(item)
    }
  }
  return res
}
 2
3
4
5
6
7
8
9
10
