【js】有趣的js编程题


一、旋转数组

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

总结

猜你喜欢

转载自blog.csdn.net/qq_48896417/article/details/128905128