有趣的js编程题
- 一、旋转数组
- 1、题目描述:
- 2、实现思路
- 1. pop与unshift方法
- 2. slice方法(不改变原数组,返回新数组)
- 2. splice方法(改变原数组)
- 二、请找出1-10000中的对称数字
- 1、题目描述:
- 2、实现思路
- 1. 筛选思路 revere倒转对比
- 2.数学规律构造思路
- 三、给定一个数组将该数组的0项放到最后
- 1、题目描述:
- 2、实现思路
- 1.filter筛选思路
- 2.push和splice思路
- 3.排序算法是思路--双指针思想
- 四、实现一个方法可以将传入的数字逆序字符串形式输出
- 1、题目描述:
- 2、实现思路
- 1.数组reserve思路
- 2.字符串递归截取思路
- 3. 数学取值思想(递归思想)
- 五、myInterval(fn,a , b, n)定时函数
- 1、题目描述:
- 2、实现思路
- 1.闭包思路
- 2.面向对象思想
- 六、rgb转成16进制的方法
- 1、题目描述:
- 2、实现思路
- 1.思路分析
- 七、promise.retry方法
- 1、题目描述:
- 2、实现思路
- 1.思路分析
- 八、数组扁平化、去重、排序
- 1、题目描述:
- 2、实现思路
- 1.思路分析
- 八、数组拼接
- 1、题目描述:
- 2、实现思路
- 1.思路分析
- 总结
一、旋转数组
1、题目描述:
传入[1, 2, 3, 4, 5, 6]数组和一个旋转的次数k返回旋转后的数据,
例子:传入[1, 2, 3, 4, 5, 6]和k=3,获得数组[4, 5, 6, 1, 2, 3]
2、实现思路
1. pop与unshift方法
function roateArr1 (arr, k) {
let step = k % arr.length;
while(k) {
let last = arr.pop();
arr.unshift(last);
k--;
};
return arr;
}
console.log(roateArr1([1, 2, 3, 4, 5, 6], 1))
2. slice方法(不改变原数组,返回新数组)
function roateArr2(arr, k) {
let step = k % arr.length;
let tem1 = arr.slice(-step);
let temp2 = arr.slice(0, arr.length - step);
return tem1.concat(temp2);
}
console.log(roateArr2([1, 2, 3, 4, 5, 6], 2))
2. splice方法(改变原数组)
function roateArr3(arr, k) {
let step = k % arr.length;
return arr.splice(-step).concat(arr);
}
console.log(roateArr3([1, 2, 3, 4, 5], 4))
二、请找出1-10000中的对称数字
1、题目描述:
// 请找出1-10000中的对称数字
// 例如:121 2442
2、实现思路
构造数据列表的几种方式
let numsArr = [...Array(10000).keys()].map(i => i + 1);
let numsArr2 = Array.from({length: 10000}, (v, i) => i + 1);
let numsArr3 = new Array(10000).fill('').map((v, i) => i + 1)
// console.log(numsArr3);
1. 筛选思路 revere倒转对比
function getLvLNums1(arr) {
return arr.filter((item, i) => item.toString().split('').reverse().join('') == item)
};
console.log(getLvLNums1(numsArr))
2.数学规律构造思路
// 2、数学规律构造
// 1、2、3、...9
// 11、22...99
// 101、111、121...191、202...292、909...999
// 1001、1111、1221....2002、2112.....9009、9119...9999
function getLvLNums2() {
let res = [];
let i = 1;
for(;i <= 9; i++) {
res.push(i);
res.push(11 * i);
for(let j = 0; j <=9; j++) {
res.push(101 * i + 10 * j);
res.push(1001 * i + 110 * j);
}
}
return res.sort((a, b) => a - b)
}
console.log(getLvLNums2())
三、给定一个数组将该数组的0项放到最后
1、题目描述:
// 给定一个数组将该数组的0项放到最后
// 例如:[1, 3, 4, 0, 22, 45, 0, 9] => [1, 3, 4, 22, 45, 9, 0, 0]
2、实现思路
1.filter筛选思路
let testArr = [1, 0, 3, 0, 0, 99, 0];
function afterZeroFn1(arr) {
return arr.filter(item => +item).concat(Array(arr.length - arr.filter(item => +item).length).fill('0').map(v => +v))
};
// console.log(afterZeroFn1(testArr));
2.push和splice思路
注意点: 需要一个变量来动态减少循环的次数
function afterZeroFn2(arr) {
let i = 0;
let num = 0;
for(;i < arr.length - num; i++) {
if (arr[i] === 0) {
arr.splice(i, 1);
arr.push(0);
num ++;
i--;
}
}
return arr;
}
// console.log(afterZeroFn2(testArr));
3.排序算法是思路–双指针思想
function afterZeroFn3(arr) {
let point1 = 0;
let i = 0;
for(;i < arr.length; i++) {
if (arr[i] === 0 && arr[point1] !== 0) {
point1 = i;
} else {
if (point1 < i && arr[i] != 0 && arr[point1] === 0) {
let temp = arr[i];
arr[point1] = temp;
arr[i] = 0;
point1 = i;
}
}
}
return arr;
}
console.log(afterZeroFn3(testArr));
四、实现一个方法可以将传入的数字逆序字符串形式输出
1、题目描述:
// 实现一个方法可以将传入的数字逆序字符串形式输出
// 例子:123 =》 ‘321’
2、实现思路
1.数组reserve思路
let str = '12345';
function strReverse1(str) {
return str.toString().split('').reverse().join('');
};
// console.log('strReverse1=>', strReverse1(str));
2.字符串递归截取思路
递归需要有一个合适的结束时机
function strReverse2(str) {
let temp = str + '';
if (temp.length === 1) return temp;
return temp.substring(temp.length - 1) + strReverse2(temp.substring(0, temp.length - 1));
}
// console.log('strReverse2=>', strReverse2(str));
3. 数学取值思想(递归思想)
递归需要有一个合适的结束时机
// 12345 -----> 12345 % 10 = 5 Math.floor(12345 / 10) = 1234
// 1234 ----> 1234 % 10 = 4 Math.floor(1234 / 10) = 123
// 123 ----> 123 % 10 = 3 Math.floor(123 / 10) = 12
// 12 ----> 12 % 10 = 2 Math.floor(12 / 10) = 1
// 1 ----> 1 % 10 = 1 Math.floor(1 / 10) = 0
function strReverse3(str) {
temp = Math.floor(str / 10);
if (temp == 0) return str % 10;
return str % 10 + '' + strReverse3(temp);
}
console.log('strReverse3=>', strReverse3(str));
五、myInterval(fn,a , b, n)定时函数
1、题目描述:
// 第一题:写一个myInterval(fn,a , b, n),
// 每次间隔a, a+b, a+2b...a+nb的时间执行fn函数,执行n次欧关闭定时器
2、实现思路
1.闭包思路
function myInterval(fn, a, b, n) {
let _a = a;
let _b = b;
let _n = n;
let count = 0;
let _fn = fn;
function inFn() {
let time = _a + count * _b;
console.log('time=>', time)
if (count >= _n) {
return;
}
setTimeout(_ => {
_fn();
count++;
inFn();
}, time)
}
inFn();
}
myInterval(function(){
console.log('myInterval....');
}, 1000, 2000, 3);// 1s 3s 5s 7s
2.面向对象思想
unction myInterval(fn, a, b, n) {
this.a = a;
this.b = b;
this.fn = fn;
this.count = 1;
this.n = n;
}
// 正确实现
myInterval.prototype.start = function() {
let delay = this.a + this.count * this.b;
let timer = setTimeout(() => {
console.log('执行函数:', this.count);
this.fn();
this.count++;
this.start();
}, delay);
if (this.count > this.n) {
clearTimeout(timer);
console.log('清理定时器');
return;
};
};
let instance = new myInterval(function(){
console.log('执行了。。');
}, 1000, 2000, 3);
instance.start();
六、rgb转成16进制的方法
1、题目描述:
// 实现一个将rgb转成16进制的方法
// 例子:rgb(255, 255, 255) ==> #ffffff
2、实现思路
1.思路分析
思路分析
1、通过正则将rgb(255, 255, 255)中的颜色值提取出来
2、将数字进行16进制转化
2.1 通过toString()方法进行进制转化
2.2 必须注意大于16的数字转化成16精致前面是不需要补0 的
let testRGB = 'rgb(255, 255, 2)';
function TranfromColor() {
this.originColor = '';
this.colorArr = [];
this.result = '#';
// rgb(255, 255, 255)
// this.colorReg = /\d+/g;
this.colorReg = /^(rgb|RGB)\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*$/;
this.get16Color = function(rgbColor) {
this.originColor = rgbColor;
if (!this.originColor) return;
this.getColorArr(this.originColor).forEach((item, idx) => {
// this.result += ('0' + Number(item).toString(16)).substr(-2);
this.result += (Number(item) > 16 ? '' : '0') + Number(item).toString(16);
// this.result += ('' + Number(item).toString(16)).padStart(2, 0);
});
return this.result;
};
this.getColorArr = (originColor) => {
let matchRes = originColor.match(this.colorReg);
if (!matchRes) return;
// console.log(matchRes, matchRes[0], matchRes[1], matchRes[2]);
matchRes[2] && this.colorArr.push(matchRes[2]);
matchRes[3] && this.colorArr.push(matchRes[3]);
matchRes[4] && this.colorArr.push(matchRes[4]);
[...Array(3).keys()].forEach((item, indx) => {
+this.colorArr[item] > 255 && (this.colorArr[item] = '255')
});
return this.colorArr;
}
}
let tranfromColor = new TranfromColor();
let color16 = tranfromColor.get16Color(testRGB);
console.log(color16)
七、promise.retry方法
1、题目描述:
// 实现一个promise.retry方法 重试异步函数
// 如果异步函数执行成功 resolve结果
// 如果异步函数执行失败 就尝试超过一定次数才进行reject
2、实现思路
1.思路分析
思路分析
1、通过await 和trycatch进行错误捕捉
2、while循环的是整个trycatch处理过程,而不是单纯的函数执行部分
Promise.retry = function(fn, times) {
return new Promise(async (resolve, reject) => {
while(true) {
try {
let res = await fn();
resolve(res);
console.log(res);
break;
} catch (error) {
if (times < 1) {
console.log('最终失败');
reject('fainaly fail');
break;
}
times--;
console.log('失败一次,剩余' + times + '次')
}
}
})
}
Promise.retry(testFn, 3).then((res) => {
console.log('okkk==>', res)
}, err => {
console.log('err===>', err);
})
八、数组扁平化、去重、排序
1、题目描述:
// 实现数组扁平化、去重、排序输出
let arrTest = [
9,
[1, 2],
[3, 4, [5, 6, 7]],
[8,0, [22, 33, 44, [55, 66]]]
];
2、实现思路
1.思路分析
思路分析
1、 核心思想 递归思想和数组concat方法
2、[].concat([1], [2], [3, 4]) => [1, 2, 3, 4]
3、[].concat(1, 2, 3, [4, 5]) => [1, 2, 3, 4, 5]
Array.prototype.flat = function() {
let arr = this;
let newArr = arr.map(item => {
if (Array.isArray(item)) {
return item.flat();
};
return [item];
});
console.log('中间状态:', newArr);
return [].concat(...newArr);
}
Array.prototype.unique = function() {
return [...new Set(this)];
}
// console.log(arrTest.flat());
Array.prototype.flat2 = function() {
let arr = this;
while(arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr);
};
console.log('中间状态2=》', arr)
return arr;
};
console.log(arrTest.flat2().unique().sort((a, b) => a -b));
八、数组拼接
1、题目描述:
// 有下面两个数组
// [A1, A2, A3, A4, B1, B2, B3, B4, C1, C2, C3, D1]
// [A, B, C, D]
// 将他们合并为新的数组:[A1, A2, A3, A4, A, B1, B2, B3, B4, B, C1, C2, C3, C, D1, D]
2、实现思路
1.思路分析
双层循环和正则判断
var arr1 = ['A1', 'A2', 'A3', 'A4', 'B1', 'B2', 'B3', 'B4', 'C1', 'C2', 'C3', 'D1'];
var arr2 = ['A', 'B', 'C', 'D'];
function getNewArr1(arr1, arr2) {
let res = arr1;
let courrIdx = 0;
for(let i = 0; i < arr2.length; i++) {
let reg = new RegExp(arr2[i]);
while (courrIdx < arr1.length) {
if (!reg.test(arr1[courrIdx])) {
res.splice(courrIdx, 0, arr2[i]);
break;
};
courrIdx++;
};
}
return res;
};
// console.log(getNewArr1(arr1, arr2));
function getNewArr2(arr1, arr2) {
let result = [];
let currIdx = 0;
for(var i = 0; i < arr1.length; i++) {
if (!arr2[currIdx]) return;
if (arr1[i].charAt(0) === arr2[currIdx]) {
result.push(arr1[i]);
} else {
result.push(arr2[currIdx]);
currIdx++;
i--;
};
if (i === arr1.length - 1) {
result.push(arr2[currIdx])
}
}
return result;
}
// console.log(getNewArr2(arr1, arr2));
总结