• 【前端知识之JS】关于数据处理的手写代码汇总


    前言

    本系列主要整理前端面试中需要掌握的知识点。本节介绍关于数据处理的手写代码汇总。


    一、实现日期格式化函数

    即将时间字符串按照用户指定的格式输出.如:yyyy年MM月dd日;yyyy.MM.dd等格式.

    const dateFormat = (dateInput,format)=>{
        var day = dateInput.getDate();
        var month = dateInput.getMonth()+1;
        var year = dateInput.getFullYear();
        format = format.replace(/yyyy/,year);
        format = format.replace(/MM/,month);
        format = format.replace(/dd/,day);
        return format
    }
    console.log(dateFormat(new Date('2020-12-09'),'yyyy年MM月dd日'));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    二、实现数组的乱序输出

    通过生成随机数的方法确定当前位置的数字与哪个位置的数字交换.

    let arr = [1,2,3,4,5,6,7]
    for(let i=0;i<arr.length;i++){
        const n = Math.round(Math.random(0,1)*(arr.length-i-1)+i);
        [arr[i],arr[n]] = [arr[n],arr[i]];
    }
    console.log(arr);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    三、实现数组求和

    实现数组求和的方法有很多,循环求和就举一个例子,另外还有reduce、递归的方法

    var arr = [1,2,3,4,5];
    var sum = 0;
    
    // 遍历实现:遍历的方法有很多,比如基本的for循环,forEach等,这里就举一个例子,因为简单
    arr.forEach((a)=>{
        sum += a;
    })
    console.log(sum);
    
    // reduce实现
    var s = arr.reduce((sum,a)=>{
        sum += a
        return sum
    },0)
    console.log(s);
    
    // 递归实现
    function getSum(array,sum){
        if(array.length == 0) return sum
        else{
            return getSum(array.slice(1),sum+array[0])
        }
    }
    console.log(getSum(arr,0));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    四、实现数组扁平化

    数组扁平化即将多层数组变为一层数组,如:[1,2,[4,3,2,6],[4,8,0,[6,7,3]]] ===》 [1,2,4,3,2,6,4,8,0,6,7,3],方法也有很多:

    var arr = [1,2,[4,3,2,6],[4,8,0,[6,7,3]]]
    // 递归实现
    const newArr = [];
    function flatten(arr){
        for(var a in arr){
            if(!Array.isArray(arr[a])){
                newArr.push(arr[a])
            }else{
                flatten(arr[a])
            }
        }
        return newArr
    }
    console.log(flatten(arr));
    
    // reduce实现
    function flatten(arr){
        return arr.reduce((newArr,a)=>{
            return newArr.concat(Array.isArray(a) ? flatten(a):a)
        },[])
    }
    console.log(flatten(arr));
    
    // 扩展运算符
    function flatten(arr){
        while(arr.some(item=>Array.isArray(item))){
            arr = [].concat(...arr)
        }
        return arr
    }
    console.log(flatten(arr));
    
    
    // split和toString
    function flatten(arr){
        return arr.toString().split(",")
    }
    console.log(flatten(arr));
    
    // ES6中的flat
    console.log(arr.flat(Infinity));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    五、实现数组去重

    ES6提供的set直接具有去重功能,如果用ES5则可以用map记录每个元素出现的个数,去除重复的元素。

    const arr = [1,2,3,4,5,1,2,3,4,5,6,7,8,7,8]
    // ES6使用数据结构集合
    console.log(Array.from(new Set(arr)));
    
    // ES5使用map存储不重复的数字
    function uniqueArray(arr){
        let map = {};
        let res = []
        for(var i=0;i<arr.length;i++){
            if(!map.hasOwnProperty(arr[i])){
                map[arr[i]] = 1;
                res.push(arr[i]);
            }
        }
        return res;
    }
    
    console.log(uniqueArray(arr))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    六、实现数组的一些方法

    实现数组的push方法:在数组最后追加元素

    // 实现数组的push方法:在数组最后追加元素
    Array.prototype.myPush = function(...args){
        for(let i=0;i<args.length;i++){
            this[this.length] = args[i]
        }
        return this.length
    }
    let arr = [1,33,3]
    arr.myPush(4,5,6)
    console.log(arr)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    实现数组的filter方法

    let arr = [1,2,3,4,5]
    Array.prototype.myFilter = function(fn){
        const arr = []
        for(let i=0;i<this.length;i++){
            if(fn(this[i])) arr.push(this[i])
        }
        return arr
    }
    var filterArr = arr.myFilter((item)=>{
        return item%2 == 0
    })
    console.log(filterArr);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    实现数组的map方法

    const arr = [1,2,3,4]
    Array.prototype.myMap = function(fn){
        const arr = [];
        if(typeof fn !== "function") console.error("参数必须为函数");
        for(let i=0;i<this.length;i++){
            arr.push(fn(this[i]))
        }
        return arr
    }
    const arrMap = arr.myMap(item=>{
        return item+1;
    })
    console.log(arrMap);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    实现ES6的flat

    function myFlat(arr,depth){
        if(!Array.isArray(arr) || depth <= 0){
            return arr
        }
        return arr.reduce(function(prev,cur){
            return Array.isArray(cur) ? prev.concat(myFlat(cur,depth-1)) : prev.concat(cur)
        },[])
    }
    console.log(myFlat(arr,2));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    七、实现字符串的一些方法

    实现字符串repeat方法:输入字符串s,以及其重复的次数,输出重复的结果,例如输入abc,2,输出abcabc。

    function repeat(s,n){
        return (new Array(n+1)).join(s);
    }
    console.log(repeat("123",3));
    
    • 1
    • 2
    • 3
    • 4

    实现字符串的翻转

    String.prototype.myReverse = function(){
        return this.split("").reverse().join("")
    }
    const str = "1234"
    console.log(str.myReverse());
    
    • 1
    • 2
    • 3
    • 4
    • 5

    八、实现将数字每千分位用逗号隔开

    const num = 123456789.3465;
    function format(n){
        let num = n.toString()
        let decimals = '';
        let integers = num;
        // 存储小数部分和整数部分
        if(num.indexOf('.') > -1){
            integers = num.split('.')[0];
            decimals = num.split('.')[1];
        }
        let len = integers.length
        if(len <= 3) return num
        else{
            let temp = '';
            let remainder = len%3
            // 判断是否为小数,如果是就令temp为小数点以及其后,若不是,则temp为空
            decimals ? temp = "." + decimals : temp
            if(remainder>0){
                return num.slice(0,remainder)+','+num.slice(remainder,len).match(/\d{3}/g).join(',')+temp
            }
            else{
                return num.slice(0,len).match(/\d{3}/g).join(',')+temp
            }
        }
    }
    console.log(format(num));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    九、实现非负大整数相加

    /* 
    JS 对数值有范围的限制,限制如下:
    Number.MAX_VALUE // 1.7976931348623157e+308
    Number.MAX_SAFE_INTEGER // 9007199254740991
    Number.MIN_VALUE // 5e-324
    Number.MIN_SAFE_INTEGER // -9007199254740991
    */
    /* 
    实现大数相加的思路:
    ● 首先用字符串的方式来保存大数,这样数字在数学表示上就不会发生变化
    ● 初始化res,temp来保存中间的计算结果,并将两个字符串转化为数组,以便进行每一位的加法运算
    ● 将两个数组的对应的位进行相加,两个数相加的结果可能大于10,所以可能要仅为,对10进行取余操作,将结果保存在当前位
    ● 判断当前位是否大于9,也就是是否会进位,若是则将temp赋值为true,因为在加法运算中,true会自动隐式转化为1,以便于下一次相加
    ● 重复上述操作,直至计算结束
    */
    function sumBigNumber(a,b){
    let res = "";
    let temp = 0
    a = a.split("");
    b = b.split("");
    while(a.length || b.length || temp){
        // ~是取非,而~~就是取两次非,实际上就是本身,但是转换为数值了
        temp += ~~a.pop()+ ~~b.pop();
        res = temp%10 + res;
        temp = temp > 9
    }
    return res.replace(/^0+/,'');
    }
    console.log(sumBigNumber('123','423'));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    十、实现add(1)(2)(3)

    /* 方法一: */
    function add(...args){
        // 对所有参数做求和操作
        return args.reduce((a,b)=>a+b)
    }
    function currying(fn){
        let args = []
        // 判断是继续传参还是在执行函数
        return function temp(...newArgs){
            // 继续传参
            if(newArgs.length){
                args = [...args,...newArgs]
                return temp
            }else{
                // 执行函数
                let val = fn.apply(this,args)
                args = []
                return val
            }
        }
    }
    let addCurry = currying(add)
    console.log(addCurry(1)(2)(3)());
    
    /* 方法二:重写toString方法 */
    function add() {
        // 将参数转换为数组
        let args = Array.prototype.slice.call(arguments)
        // 陆续向args中添加后续参数
        let inner = function () {
            args.push(...arguments)
            return inner
        }
        // 重写toString方法,直接得到参数之和的字符串
        inner.toString = function () {
            return args.reduce(function (pre, cur) {
                return pre += cur
            })                                 
        }
    
        return inner;
    }
    
    let test = add(1)(2)(3).toString()
    console.log(test);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    十一、实现类数组转化为数组

    var a= {};
    var i = 0;
    for(i=0; i<10 ; i++){
        a[i] = i*i;
    }
    a.length = i;
    var total = 0;
    for(var j=0; j< a.length; j++){
        total += a[j];
    }
    console.log(a);
    // console.log(Array.prototype.slice.call(a));
    console.log(Array.prototype.splice.call(a,0));
    // console.log(Array.prototype.concat.apply([],a));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    十二、使用reduce求和

    // arr1 = [1,2,3,4,5,6,7,8,9]求和
    let arr1 = [1,2,3,4,5,6,7,8,9];
    let sum1 = arr1.reduce((a,b)=>{
        return a+b;
    })
    console.log(sum1)
    
    // arr2 = [1,2,[3,4],5,6,[7,8,9]]求和
    let arr2 = [1,[2,3],4,5,6,7,8,9];
    function getSum2(arr){
        let sum2 = arr.reduce((a,b)=>{
            if(Array.isArray(b)){
                return a+getSum2(b)
            }else{
                return a+b
            }
        },0)
        return sum2
    }
    console.log(getSum2(arr2))
    
    // arr3 = [{a:1, b:3}, {a:2, b:3, c:4}, {a:3}]求和
    let arr3 = [{a:1, b:3}, {a:2, b:3, c:4}, {a:3}];
    function getSum3(arr){
        let sum3 = arr.reduce((a,b)=>{
            if(typeof b === "object"){
                a += getObjSum(b);
            }else{
                a += b
            }
            return a
        },0)
        return sum3
    }
    function getObjSum(obj){
        let  s = 0;
        for(o in obj){
            s += obj[o]
        }
        return s
    }
    console.log(getSum3(arr3));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    十三、ES5和ES6求函数参数的和

    // ES5方法
    function sum(){
        let sum = 0
        Array.prototype.forEach.call(arguments,function(item){
            sum += item;
        })
        return sum;
    }
    console.log(sum(1,2,3,4,5));
    
    // ES6方法
    function sum(...args){
        let sum = 0;
        args.forEach(item=>{
            sum += item
        })
        return sum;
    }
    console.log(sum(1,2,3,4,5));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    十四、解析URL Params为对象

    /* 
    let url = 'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled';
    parseParam(url)
    结果
    { user: 'anonymous',
      id: [ 123, 456 ], // 重复出现的 key 要组装成数组,能被转成数字的就转成数字类型
      city: '北京', // 中文需解码
      enabled: true, // 未指定值得 key 约定为 true
    }
    */
    
    function parseParam(url){
        const paramsStr = /.+\?(.+)$/.exec(url)[1];
        const paramsArr = paramsStr.split('&');
        let paramsObj = {};
        // 将params存到对象中
        paramsArr.forEach(param=>{
            if(/=/.test(param)){
                let [key,val] = param.split('=');
                val = decodeURIComponent(val);
                val = /^d+$/.test(val) ? parseFloat(val) :val;
                if (paramsObj.hasOwnProperty(key)) { // 如果对象有 key,则添加一个值
                    paramsObj[key] = [].concat(paramsObj[key], val);
                } else { // 如果对象没有这个 key,创建 key 并设置值
                    paramsObj[key] = val;
                }
            } else { // 处理没有 value 的参数
                paramsObj[param] = true;
            }
        })
        return paramsObj;
    }
    
    let url = 'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled';
    console.log(parseParam(url));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    十五、有序二维数组查找目标值

    /*
    有序二维数组:任何一个位置的数字,都满足它的左边和上边比它小,它的右边和下边比它大。
    array = [[1,2,3,4],
            [5,7,10,12],
            [6,8,14,16],
            [9,11,15,17]]
    */
    function findTwoArray(array,target){
        if(array == [] || array.length == 0){
            return false;
        }
        let row = 0;
        let colum = array[0].length-1;
        while(row<array.length && colum>=0){
            if(array[row][colum]<target){
                row++;
                
            }else if(array[row][colum]>target){
                colum--;
            }else{
                console.log(row,colum);
                return true;
            }
        }
        return false;
    }
    let array = [[1,2,3,4],[5,7,10,12],[6,8,14,16],[9,11,15,17]]
    let target = 14;
    console.log(findTwoArray(array,target));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    十六、二维数组斜向打印

    function printMatrix(arr){
        let result = [];
        let m = arr.length;
        let n = arr[0].length;
        for(let k=0;k<n;k++){
            for(let i=0,j=k;i<m && j>=0;i++,j--){
                result.push(arr[i][j])
            }
        }
        for(let k = 1;k<m;k++){
            for(let i=k,j=n-1;i<m&&j>=0;i++,j--){
                result.push(arr[i][j])
            }
        }
        return result
    }
    let array = [[1,2,3,4],[5,7,10,12],[6,8,14,16],[9,11,15,17]]
    console.log(printMatrix(array))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    Python函数
    大学四年庸庸碌碌,我弯道超车上了软件测试
    超声波传感器(CHx01&ICU-x0201&ICU-30201) - 资源抢先看(资料获取)
    酷开科技丨这么好用的酷开系统,不用真的会后悔!
    万物皆可集成系列:低代码通过Web API
    Linux操作系统的发展
    Lightroom“夏日清凉”调色思路
    【计算机网络】 集线器、网桥、交换机、路由器看这一篇就懂了。实验: 路由器的作用,以及没有路由器的情况下,如何用三层交换机实现路由器的功能
    TransactionScope的使用
    【微服务】微服务架构
  • 原文地址:https://blog.csdn.net/weixin_44337386/article/details/126094047