🧭 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); // 8
1
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