最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 一道统计题到reduce方法的学习

    正文概述 掘金(fifthThirteen)   2021-08-24   408

    引出题目

    // 我的解答
    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]
    

    起源地下载网 » 一道统计题到reduce方法的学习

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元