首页>国内 > 正文

JavaScript 高级单行代码详解

2023-03-13 19:19:26来源:web前端开发


(资料图片仅供参考)

1. 通过键对对象数组进行分组

我们定义了一个名为 groupBy 的函数,它以一个对象数组和一个键作为参数。该函数的目的是将数组中的对象按指定的键进行分组。

const groupBy = (arr, key) => arr.reduce(  (acc, obj) => ({ ...acc, [obj[key]]: [...(acc[obj[key]] || []), obj] }),  {} )const people = [ { name: "Alice", age: 21 }, { name: "Bob", age: 22 }, { name: "Charlie", age: 21 }, { name: "David", age: 23 }, { name: "Eve", age: 22 }]console.log(groupBy(people, "age"))/* Output:{ 21: [  { name: "Alice", age: 21 },  { name: "Charlie", age: 21 } ], 22: [  { name: "Bob", age: 22 },  { name: "Eve", age: 22 } ], 23: [{ name: "David", age: 23 }]}*/

acc 参数是累加分组对象的累加器。obj 参数表示数组中的每个对象。

在 reduce() 方法内部,使用扩展运算符 (...acc) 返回一个新对象。这将创建 accumulator 对象的浅表副本,以便可以在不更改原始对象的情况下对其进行修改。

新对象的属性设置为与 key 参数的值相匹配的键。该属性的值是一个包含被迭代对象的数组。

(acc[obj[key]] || []) 表达式检查该属性是否存在于累加器对象中。如果不存在,则返回一个空数组。展开运算符用于将数组与正在迭代的当前对象连接起来。

最后,groupBy() 函数返回包含分组对象的累加器对象。

2. 返回数组的中位数

我们实现了一个名为 median 的函数,它将一个数字数组作为输入,按升序对其进行排序,并返回排序后的数组的中值。

当数组的元素个数为奇数时,排序数组的中值就是中间的元素。当数组元素个数为偶数时,中值取中间两个元素的平均值。

const median = (arr) => { const sorted = arr.sort() const middle = Math.floor(sorted.length / 2) return sorted.length % 2 === 0  ? (sorted[middle - 1] + sorted[middle]) / 2  : sorted[middle]}const oddArr = [3, 1, 4, 2, 5]console.log(median(oddArr)) // 3const evenArr = [1, 2, 5, 6]console.log(median(evenArr)) // 3.5

第一个例子,输入数组[3, 1, 4, 2, 5]被排序为[1, 2, 3, 4, 5],中间元素为3。因此,输入数组的中值 是 3。

在第二个例子中,输入数组[1,2,5,6]被排序为[1,2,5,6],中间两个元素为2和5。因此,输入数组的中值为 (2 + 5) / 2 = 3.5。

3.返回数组的模式

数组的众数是数组中出现频率最高的值。如果有多个值具有相同的最高频率,则所有这些值都被视为众数。

const mode = (arr) => { const counts = arr.reduce(  (acc, curr) => ({ ...acc, [curr]: (acc[curr] || 0) + 1 }),  {}    ) const maxCount = Math.max(...Object.values(counts)) return Object.keys(counts)  .filter((key) => counts[key] === maxCount)  .map(Number)}const arr1 = [1, 2, 3, 2, 4, 2, 5]console.log(mode(arr1)) // [2]const arr2 = [1, 2, 3, 2, 4, 4, 5]console.log(mode(arr2)) // [2, 4]

在第一个示例中,输入数组 [1, 2, 3, 2, 4, 2, 5] 的计数为 { 1: 1, 2: 3, 3: 1, 4: 1, 5: 1 }。最高计数为 3,出现值 2。因此,输入数组的模式为 [2]。

在第二个示例中,输入数组 [1, 2, 3, 2, 4, 4, 5] 的计数为 { 1: 1, 2: 2, 3: 1, 4: 2, 5: 1 }。最高计数为 2,出现在值 2 和 4 中。因此,输入数组的模式为 [2, 4]。

4. 使用扩展运算符和 Array.from 创建一个长度为 n 的数组

使用扩展运算符和 Array.from() 创建一个长度为 n 的新数组。生成的数组包含从 0 到 n-1 的升序排列的数字。

const n = 5const arr = [...Array.from({ length: n }, (_, index) => index)]console.log(arr) // [ 0, 1, 2, 3, 4 ]

在此示例中,n 设置为 5,因此,生成的数组 arr 的长度为 5。数组的值是使用函数 (_, index) => index 生成的,该函数返回数组的当前索引。因此,结果数组将为 [0, 1, 2, 3, 4]。

5. 使用解构获取数组的最后一个元素

此函数的目的是使用解构获取数组的最后一个元素。

const last = (arr) => [...arr].pop()const people = [ { name: "Alice", age: 21 }, { name: "Bob", age: 22 }, { name: "Charlie", age: 21 }, { name: "David", age: 23 }, { name: "Eve", age: 22 }]console.log(last(people)) // { name: "Eve", age: 22 }

在 last() 函数内部,展开运算符 (...) 用于创建原始数组的副本。这是必需的,因为 pop() 方法会修改原始数组并返回删除的元素。

然后,对数组的副本调用 pop() 方法,删除并返回数组的最后一个元素。由于在调用 pop() 方法之前复制了数组,因此不会修改原始数组。

last() 函数返回数组的最后一个元素。

6. 使用布尔构造函数检查变量是否为真

我们函数的目的是使用布尔构造函数检查变量是否为真。

布尔构造函数是 JavaScript 中的一个内置函数,可将值转换为布尔值。如果该值为 truthy,则布尔构造函数返回 true。如果该值为 falsy,则布尔构造函数返回 false。

const isTruthy = (val) => Boolean(val)console.log(isTruthy(false)) // falseconsole.log(isTruthy(0)) // falseconsole.log(isTruthy(-0)) // falseconsole.log(isTruthy(0n)) // falseconsole.log(isTruthy("")) // falseconsole.log(isTruthy(null)) // falseconsole.log(isTruthy(undefined)) // falseconsole.log(isTruthy(NaN)) // falseconsole.log(isTruthy(true)) // trueconsole.log(isTruthy({})) // trueconsole.log(isTruthy([])) // trueconsole.log(isTruthy(42)) // trueconsole.log(isTruthy("0")) // trueconsole.log(isTruthy("false")) // trueconsole.log(isTruthy(new Date())) // trueconsole.log(isTruthy(Infinity)) // true
7. 从数组中删除虚假值

布尔构造函数用作 filter() 方法的回调函数。如果值为真,则布尔构造函数返回真,如果值为假,则返回假。因此,filter() 方法从原始数组中删除所有虚假值。

const compact = (arr) => arr.filter(Boolean)const falsyArr = [false, 0, -0, 0n, "", null, undefined, NaN]const mixArr = [true, false, {}, 0, [], "", "0", null, "false", undefined, 42]console.log(compact(falsyArr)) // []console.log(compact(mixArr)) // [ true, {}, [], "0", "false", 42 ]

在 compact() 函数内部,使用布尔构造函数作为回调函数对 arr 参数调用 filter() 方法。这将返回一个新数组,其中仅包含原始数组的真值。

compact() 函数返回新数组。

当执行 console.log() 语句时,compact(falsyArr) 的输出是一个空数组,因为 falsyArr 数组中的所有值都是假的。compact(mixArr) 的输出是一个数组,它只包含 mixArr 数组的真实值,即 true、一个空对象 {}、一个空数组 []、字符串“0”、字符串“false”,以及 数字 42。所有虚假值(false、0、""、null、undefined 和 NaN)都已从 mixArr 数组中删除。

8. 将字符串数组转换为数字

函数的目的是将字符串数组转换为数字数组。Number 构造函数用作 map() 方法的回调函数。Number 构造函数将字符串转换为数字。

const toNumbers = (arr) => arr.map(Number)const strArr = ["1", "2", "3", "4", "5"]console.log(toNumbers(strArr)) // [ 1, 2, 3, 4, 5 ]

在 toNumbers() 函数内部,使用 Number 构造函数作为回调函数对 arr 参数调用 map() 方法。这将返回一个包含转换值的新数组。

9. 返回一个键值翻转的对象

此函数的目的是返回一个新对象,其中翻转了原始对象的键和值。

Object.entries() 方法用于从原始对象创建键值对数组。然后使用 map() 方法迭代数组中的每个键值对,并返回一个新的翻转键值对数组。最后,使用 Object.fromEntries() 方法从翻转的键值对数组中创建一个新对象。

const flip = (obj) => Object.fromEntries(Object.entries(obj).map(([key, value]) => [value, key]))const myDog = { firstName: "oscar", lastName: "king", age: 3}console.log(flip(myDog)) // { 3: "age", oscar: "firstName", king: "lastName" }

在 flip() 函数内部,对 obj 参数调用 Object.entries() 方法以创建键值对数组。然后,在键值对数组上调用 map() 方法。对于每个键值对,map() 方法解构键和值变量,并返回一个新数组,其中值作为第一个元素,键作为第二个元素。这将创建一个翻转的键值对数组。

最后,在翻转的键值对数组上调用 Object.fromEntries() 方法以使用翻转的键值对创建一个新对象。

flip() 函数返回新对象。

执行 console.log() 语句时,输出是一个新对象,其中翻转了原始 myDog 对象的键和值。firstName 键及其值“oscar”已翻转为“oscar”键及其值“firstName”。lastName 键及其值“king”已翻转为“king”键及其值“lastName”。age 键及其值 3 已翻转为 3 键及其值“age”。

10. 返回一个只有特定键的对象

此函数的目的是返回一个新对象,该对象仅包含原始对象中指定的键及其对应的值。

const pick = (obj, keys) => Object.fromEntries(  Object.entries(obj).filter(([key]) => keys.includes(key)) )const myDog = { firstName: "oscar", lastName: "king", age: 3}console.log(pick(myDog, [])) // {}console.log(pick(myDog, ["firstName"])) // { firstName: "oscar" }console.log(pick(myDog, ["firstName", "lastName"])) // { firstName: "oscar", lastName: "king" }

在 pick() 函数内部,对 obj 参数调用 Object.entries() 方法以创建键值对数组。然后,在键值对数组上调用 filter() 方法。对于每个键值对,filter() 方法解构键变量,如果键数组包含键则返回 true。这将创建一个过滤后的键值对数组。

最后,在过滤后的键值对数组上调用 Object.fromEntries() 方法来创建一个仅包含指定键及其对应值的新对象。pick() 函数返回新对象。

11. 返回一个只有唯一值的对象

此函数 uniqueValues 将一个对象作为参数并返回一个新对象,该对象仅包含来自输入对象的唯一值。

const uniqueValues = (obj) => Object.fromEntries(  Object.entries(obj).filter(   ([key, value], index, entries) =>    entries.findIndex(([k, v]) => v === value) === index  ) )const myDog = { id: 3, firstName: "oscar", lastName: "oscar", age: 3}console.log(uniqueValues(myDog)) // { id: 3, firstName: "oscar" }

它首先在输入对象上调用 Object.entries() 方法以获取键值对数组。然后,它使用 filter() 方法过滤条目数组,并仅返回值唯一的条目。

要检查一个值是否唯一,它在原始条目数组上使用 findIndex() 方法。它查找与当前过滤的条目具有相同值的第一个条目的索引。如果当前条目的索引等于第一个匹配条目的索引,则意味着该值是唯一的,应该包含在结果对象中。

最后,它使用 Object.fromEntries() 方法将过滤后的条目数组转换回对象。

在示例代码中,使用具有某些重复值的对象 myDog 调用 uniqueValues 函数。该函数返回一个仅包含唯一值并删除重复值的新对象。生成的对象具有 id:3 和 firstName:"oscar"。

关键词:

相关新闻

Copyright 2015-2020   三好网  版权所有 联系邮箱:435 22 640@qq.com  备案号: 京ICP备2022022245号-21