本系列主要整理前端面试中需要掌握的知识点。本节介绍关于数据处理的手写代码汇总。
即将时间字符串按照用户指定的格式输出.如: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'));
/* 方法一: */
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));
// 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方法
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));
/*
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))