# 牛客网评测

# 移除数组中的元素(返回原数组)

输入:[1,2,2,3,4,2,2], 2
输出: [1,3,4]
1
2
function removeWithoutCopy(arr, item) {
 for(let i=arr.length;i>=0;i--){
    if(arr[i]==item){
        arr.splice(i,1);
    }
 }
 return arr;
}

// 另一种写法,记得删除元素后位置往前移
function removeWithoutCopy(arr, item) {
    for(let i = 0; i< arr.length; i++) {
        if(arr[i]===item) {
            arr.splice(i,1);
            i--;
        }
    }
 return arr;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 计数

输入:[1,2,4,4,3,4,3], 4
输出: 3
1
2
function count(arr, item) {
    let res = arr.reduce( (init,curr)=> {
    //如果当前置等于item,该函数值加一
    return curr === item ? init+1:init;
    },0)
    return res;
} 
1
2
3
4
5
6
7

# 查找重复元素

找出数组重复出现过的元素

function duplicates(arr) {
 var resArr=[];
 arr.forEach(v => {
 //判断原数组是否有重复数据
 //判断结果数组是否已经具有该数据
    if(arr.indexOf(v) !=arr.lastIndexOf(v) && resArr.indexOf(v) == -1){
        resArr.push(v);
    }
 });
 return resArr;
} 
1
2
3
4
5
6
7
8
9
10
11

# 计时器

实现一个打点计时器,要求

  1. startend(包含 startend),每隔 100 毫秒 console.log一个数字,每次数字增幅为 1
  2. 返回的对象中需要包含一个 cancel 方法,用于停止定时操作
  3. 第一个数需要立即输出
function count(start, end) {
 //立即输出第一个值
 console.log(start++);
 var timer = setInterval(
 function() {
    if(start <= end){
        console.log(start++);
    }else{
        clearInterval(timer);
    }
 },100);
 //返回一个对象
 return {
    cancel : function() {
        clearInterval(timer);
    }
 };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 使用闭包

实现函数 makeClosures,调用之后满足如下条件:

  1. 返回一个函数数组 result,长度与 arr 相同
  2. 运行 result 中第 i 个函数,即 result[i](),结果与 fn(arr[i]) 相同
function makeClosures(arr, fn) {
 let result = [];
 for (let i of arr) {
    result.push(()=>{
        return fn(i)
    });
 }
 return result;
}
1
2
3
4
5
6
7
8
9

# 二次封装函数

已知函数 fn 执行需要 3 个参数。请实现函数 partial,调用之后满足如下条件:

  1. 返回一个函数 result,该函数接受一个参数
  2. 执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致
function partial(fn, str1, str2) {
 return result = function (str3) {
    return fn(str1, str2, str3)
 };
} 
1
2
3
4
5

# 乘法

ab 相乘的值,ab 可能是小数,需要注意结果的精度问题

function multiply(a, b) {
    // 先将数字转换为字符串
    let str1 = a.toString();
    let str2 = b.toString();
    // 获取两个数的小数位数
    let lenA = (str1.indexOf('.')==-1)?0:(str1.length-str1.indexOf(".")-1);
    let lenB = (str2.indexOf('.')==-1)?0:(str2.length-str2.indexOf(".")-1);
    // 比较两数的精度/位数,精度大的作为结果数精度
    let len = Math.max(lenA,lenB);
    // 运算结果
    let result = parseFloat(a*b).toFixed(len);
    return result
} 
1
2
3
4
5
6
7
8
9
10
11
12
13

# 对象属性遍历

找出对象 obj 不在原型链上的属性(注意这题测试例子的冒号后面也有一个空格~)

  1. 返回数组,格式为 key: value
  2. 结果数组不要求顺序
function iterate(obj) {
 let result = [];
 for(let key in obj){
    if(obj.hasOwnProperty(key)){
        result.push(key+': '+obj[key]);//使用obj.key部分代码不能通过
    }
 }
 return result;
}
1
2
3
4
5
6
7
8
9

TIP

其他解法:

  1. 利用Object.key()然后得到key属性,循环遍历即可
  2. 还可以利用Object.getOwnPropertyNames()