引出题目
// 我的解答
console.log('标签的数量: '
+ new Set([...document.getElementsByTagName('*')].map(tag => tag.tagName)).size)
/**
* num 统计的html数量
* arr 需要被统计的对象数组
*/
let htmlArr = [...document.getElementsByTagName('*')].map(tag => tag.tagName)
function getHtmlInfo (arr, num) {
let len = arr.length
let obj = {}
let newArr = []
let tag
for(let i = 0; i < len; i++) {
tag = arr[i]
if (obj[tag]) {
obj[tag]++
} else {
obj[tag] = 1
}
}
for (let key in obj) {
newArr.push({
tag: key,
count: obj[key]
})
}
// 降序
newArr.sort((a, b) => {
return b.count - a.count
})
let newNum = num || newArr.length
return newArr.slice(0, newNum)
}
let newHtmlArr = getHtmlInfo(htmlArr, 3)
console.log(`出现最多的是${newHtmlArr[0].tag}标签,共${newHtmlArr[0].count}次`)
console.log(`出现次数第二的是${newHtmlArr[1].tag}标签,共${newHtmlArr[1].count}次`)
console.log(`出现次数第三的是${newHtmlArr[2].tag}标签,共${newHtmlArr[2].count}次`)
// 比较low
// 大佬的解答
Object.entries([...document.querySelectorAll("*")].map(tag=>tag.tagName).reduce((ret, i)=>{
ret[i] = (ret[i] || 0) + 1;
return ret;
}, {})).sort((a, b)=>(b[1] - a[1])).slice(0, 3)
.map(a=>(`${a[0]}: ${a[1]}次`)).join(', ')
语法
arr.reduce(callback(accumulator, currentValue[, currentIndex[, sourceArray]])[, initialValue])
accumulator
累计器累计回调的返回值currentValue
当前值currentIndex
可选当前索引sourceArray
可选源数组
callback需要注意的点
accumulator
默认值为initialValue
,此时currentValue
为数组的0号索引的值,currentIndex
为0;如果initialValue
没有提供,则initialValue
取数组的0号索引位置的值,currentValue
取1号索引的值,currentIndex
为1。- 如果数组为空数组且没有提供
initialValue
,则会报类型错误。 - 如果数组只有一个元素(任意位置),且没有提供
initialValue
,或提供了initialValue
但数组为空,则callback不会被执行,该元素会被作为返回值。 - 值会被累计到
accumulator
,并最终与最后索引的值处理后合并为单一值返回。 - 建议,为安全着想,每次提供
initialValue
。
使用场景
计算数组中所有值的和
const sum = [1, 2, 3, 4].reduce((acc, cur) => acc + cur, 0)
console.log(sum) // 10
累加对象数组中的值
const sum = [{x: 1}, {x: 2}, {x: 3}].reduce((acc, cur) => acc + cur.x, 0)
console.log(sum) // 6
将二维数组转化为一维数组
const arr = [[0, 1], [2, 3], [4, 5]].reduce((acc, cur) => acc.concat(cur), [])
console.log(arr) // [0, 1, 2, 3, 4, 5]
计算数组中每个元素出现的次数
const htmls = ['html', 'span', 'body', 'div', 'div']
const countedHtmls = htmls.reduce((acc, cur) => {
if (cur in acc) {
acc[cur]++
} else {
acc[cur] = 1
}
return acc
}, {})
console.log(countedHtmls) // { html: 1, span: 1, body: 1, div: 2 }
// 计算当前页面出现次数最多的3个标签
Object.entries([...document.querySelectorAll('*')].map(tag => tag.tagName).reduce((acc,cur) => {
acc[cur] = (acc[cur] || 0) + 1
return acc
}, {})).sort((a, b) => b[1] - a[1]).slice(0, 3).map(a => `${a[0]}: ${a[1]}次`).join(', ')
按属性对object分类
const arr = [
{
name: 'css',
age: 18
},
{
name: 'Javascript',
age: 20
},
{
name: 'html',
age: 18
}
]
function groupBy (arr, property) {
return arr.reduce((acc, cur) => {
const key = cur[property]
if (!acc[key]) {
acc[key] = []
}
acc[key].push(cur)
return acc
}, {})
}
console.log(groupBy(arr, 'age'))
// {
// '18': [ { name: 'css', age: 18 }, { name: 'html', age: 18 } ],
// '20': [ { name: 'Javascript', age: 20 } ]
// }
合并对象数组中的数组
const friends = [
{
name: 'javascript',
books: ['es6入门', 'javascript高级程序设计', '你不知道的javascript', 'Dom编程艺术', 'Javascript设计模式']
},
{
name: 'css',
books: ['css世界']
}
]
const allBooks = friends.reduce((acc, cur) => {
return [...acc, ...cur.books]
}, [])
console.log(allBooks)
// [
// 'es6入门',
// 'javascript高级程序设计',
// '你不知道的javascript',
// 'Dom编程艺术',
// 'Javascript设计模式',
// 'css世界'
// ]
数组去重
const arr = [1,2,1,2,3,5,4,5,3,4,4,4,4]
const result = arr.sort().reduce((acc, cur) => {
if (!acc.includes(cur)) {
acc.push(cur)
}
return acc
}, [])
console.log(result)
// [ 1, 2, 3, 4, 5 ]
按顺序运行promise
function runPromiseInSequence(arr, input) {
return arr.reduce((promiseChain, currentFunction) => {
return promiseChain.then(currentFunction)
}, Promise.resolve(input))
}
// function runPromiseInSequence(arr, input) {
// return arr.reduce((promiseChain, currentFunction) => {
// return promiseChain.then(currentFunction)
// }, new Promise(resolve => {
// resolve(input)
// }))
// }
function p1 (a) {
return new Promise((resolve, reject) => {
resolve(a * 5)
})
}
function p2 (a) {
return new Promise((resolve, reject) => {
resolve(a * 2)
})
}
function f3 (a) {
return a * 3
}
function p4 (a) {
return new Promise((resolve, reject) => {
resolve(a * 4)
})
}
const promiseArr = [p1, p2, f3, p4]
runPromiseInSequence(promiseArr, 10).then(console.log)
// 1200
管道机制/功能型函数管道
// 管道机制/功能型函数管道
// 定义:前一个函数的输出是后一个函数的输入
// const pipeLine = (...funcs) => input => {
// return funcs.reduce((acc, curFun) => curFun(acc), input)
// }
const pipeLine = (...funcs) => input => funcs.reduce((acc, curFn) => curFn(acc), input)
const fun1 = num => num + num
const fun2 = num => num * num
const fun3 = num => num * 10
const pipeResult = pipeLine(fun1, fun2, fun3)
console.log(pipeResult(1)) // 40
实现map
if (!Array.prototype.mapUsingReduce) {
Array.prototype.mapUsingReduce = function (callback, thisArg) {
return this.reduce(function (mappedArray, currentValue, index, orignArray) {
mappedArray[index] = callback.call(thisArg, currentValue, index, orignArray)
return mappedArray
}, [])
}
}
const newArr = [1, 2, , 3].mapUsingReduce((currentValue, index, array) => currentValue + index + array.length)
console.log(newArr) // [5, 7, , 10]
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!