1.实现flat函数
> const animals = ["🐷", ["🐶", "🐂"], ["🐎", ["🐑", ["🐲"]], "🐛"]];
>
> // 不传参数时,默认“拉平”一层
> animals.flat();
> // ["🐷", "🐶", "🐂", "🐎", ["🐑",["🐲"]], "🐛"]
>
> // 传入一个整数参数,整数即“拉平”的层数
> animals.flat(2);
> // ["🐷", "🐶", "🐂", "🐎", "🐑", ["🐲"], "🐛"]
>
> // Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组
> animals.flat(Infinity);
> //["🐷", "🐶", "🐂", "🐎", "🐑", "🐲", "🐛"]
>
> // 传入 <=0 的整数将返回原数组,不“拉平”
> animals.flat(0);
> animals.flat(-10);
> //["🐷", ["🐶", "🐂"], ["🐎", ["🐑", ["🐲"]], "🐛"]];
>
> // 如果原数组有空位,flat()方法会跳过空位。
> ["🐷", "🐶", "🐂", "🐎",,].
> flat();
> // ["🐷", "🐶", "🐂", "🐎"]
- 简单实现
let a=[1,2,[3,[4,5],6],7,[{tt:2},[1,2]]]
let newA=[];
function flat(a){
for(let i=0;i<a.length;i++){
if(Array.isArray(a[i])){
flat(a[i]);
}else{
newA.push(a[i]);
}
}
}
flat(a)
newA
- 第二问:用 reduce 实现 flat 函数
let a=[1,2,[3,[4,5],6],7,[{tt:2},[1,2]]]
const flat=(arr)=>arr.reduce((pre,cur)=>{
return pre.concat(Array.isArray(cur)?flat(cur):cur)
},[])
let newA=flat(a);
newA
- 第三问:实现在原型链上重写 flat 函数
Array.prototype.fakeFlat = function(num = 1) {
if (!Number(num) || Number(num) < 0) {
return this;
}
let arr = [...this];
while (num ) {
if(arr.some(item=>Array.isArray(item))) {
arr = [].concat(... arr);
num--;
}else{
break;
}
}
return arr;
};
引用:面试官连环追问:数组拍平(扁平化) flat 方法实现
2.写一个方法将一个数组随机打乱
let a=[1,2,3,4,5,6,7,8];
a.sort(()=>Math.random()-0.5)
a
let a=[1,2,3,4,5,6,7,8];
for(let i=0;i<a.length;i++){
let temp=parseInt(Math.random()*(a.length-1));
[a[i],a[temp]]=[a[temp],a[i]]
}
引用: 写一个方法将一个数组随机打乱
3.实现一个分配随机红包的算法
function randomPacket(money,count){
//先给每个红包赋值为最低0.01元
let minMoney=0.01;
let result=new Array(count).fill(minMoney);
let realMoney=money-count*minMoney;
for(let i=0;i<count-1;i++){
if(realMoney>0){
//toFixed()返回的是一个字符串,不要忘了用parseFloat()包裹起来
let value=parseFloat((Math.random()*realMoney).toFixed(2));
result[i]=result[i]+value;
realMoney=realMoney-value;
}
}
result[count-1]+=parseFloat(realMoney.toFixed(2));
return result;
}
let arr=randomPacket(10,10)
let sum1 = arr.reduce((pre, cur) => {
cur += pre
return cur
}, 0)
console.log('arr:', arr)
console.log('sum:', parseFloat(sum1.toFixed(10)))
4.柯里化 add(1)(2)(3)
const curry = (fn, ...args) =>
// 函数的参数个数可以直接通过函数数的.length属性来访问
args.length >= fn.length // 这个判断很关键!!!
// 传入的参数大于等于原始函数fn的参数个数,则直接执行该函数
? fn(...args)
/**
* 传入的参数小于原始函数fn的参数个数时
* 则继续对当前函数进行柯里化,返回一个接受所有参数(当前参数和剩余参数) 的函数
*/
: (..._args) => curry(fn, ...args, ..._args);
function add1(x, y, z) {
return x + y + z;
}
const add = curry(add1);
console.log(add(1, 2, 3));
console.log(add(1)(2)(3));
console.log(add(1, 2)(3));
console.log(add(1)(2, 3));
// 实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;
function add() {
// 第一次执行时,定义一个数组专门用来存储所有的参数
var _args = Array.prototype.slice.call(arguments);
// 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
var _adder = function() {
_args.push(...arguments);
return _adder;
};
// 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
_adder.toString = function () {
return _args.reduce(function (a, b) {
return a + b;
});
}
return _adder;
}
add(1)(2)(3) // 6
add(1, 2, 3)(4) // 10
add(1)(2)(3)(4)(5) // 15
add(2, 6)(1) // 9
引用:
5.求"对象"深度
如如果"对象"是普通值,返回1,如果"对象"是引用类型,返回2,如果"对象"内为引用类型,且包含其他引用类型,+1并返回
案例:
//例1
1 => 1
//例2
[1, 2, 3] => 2
//例3
{name: 'abc'} => 2
//例4
{
name: 'abc',
key: {
name2: 'cba'
}
} =>3
//例5
[1, 2,[2, 3], 1] => 3
代码:
function deep(obj,num=1,max=1){
if(obj instanceof Object){
num++;
for(let key in obj){
max=Math.max(deep(obj[key],num,max),num);
}
}
return max
}