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

前言

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

文章目录

  • 前言
  • 一、实现日期格式化函数
  • 二、实现数组的乱序输出
  • 三、实现数组求和
  • 四、实现数组扁平化
  • 五、实现数组去重
  • 六、实现数组的一些方法
  • 七、实现字符串的一些方法
  • 八、实现将数字每千分位用逗号隔开
  • 九、实现非负大整数相加
  • 十、实现add(1)(2)(3)
  • 十一、实现类数组转化为数组
  • 十二、使用reduce求和
  • 十三、ES5和ES6求函数参数的和
  • 十四、解析URL Params为对象
  • 十五、有序二维数组查找目标值
  • 十六、二维数组斜向打印


一、实现日期格式化函数

即将时间字符串按照用户指定的格式输出.如: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日'));

二、实现数组的乱序输出

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

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);

三、实现数组求和

实现数组求和的方法有很多,循环求和就举一个例子,另外还有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,[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));

五、实现数组去重

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))

六、实现数组的一些方法

实现数组的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)

实现数组的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);

实现数组的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);

实现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));

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

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

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

实现字符串的翻转

String.prototype.myReverse = function(){
    return this.split("").reverse().join("")
}
const str = "1234"
console.log(str.myReverse());

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

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));

九、实现非负大整数相加

/* 
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'));

十、实现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);

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

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));

十二、使用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));

十三、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));

十四、解析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));

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

/*
有序二维数组:任何一个位置的数字,都满足它的左边和上边比它小,它的右边和下边比它大。
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));

十六、二维数组斜向打印

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))

你可能感兴趣的:(前端知识之JS,javascript,前端,开发语言)