牛客网首页 > 在线编程 > JS能力测评经典题
https://www.nowcoder.com/ta/js-assessment
本文整理了牛客网前端JS能力测评题的部分答案解析,解析源自于在牛客网中每道题的讨论界面。
文章目录
1.查找数组元素位置
- 题目描述:
找出元素 item 在给定数组 arr 中的位置
如果数组中存在 item,则返回元素在数组中的位置,否则返回 -1。 - 示例:
输入[ 1, 2, 3, 4 ], 3
输出2
我的方法:一是用for循环,二是直接用return arr.indexOf(item);
;
看了网友们的讨论,发现自己没有检验浏览器是否支持indexOf()
- 本题应注意:
- 判断当前浏览器环境中Array原型中有没有indexOf方法,若没有则执行自定义方法
- indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
解决方法:
function indexOf(arr, item) {
if (Array.prototype.indexOf){
return arr.indexOf(item);
} else {
for (var i = 0; i < arr.length; i++){
if (arr[i] === item){
return i;
}
}
}
return -1;
}
以下方法 支持数组arr中的数据类型为对象,数组,等。
function indexOf(arr, item) {
if (!arr || !arr.length) {
return -1;
}
for (var i = 0, len = arr.length; i < len; i++) {
// 支持 arr[i] 为对象,数组等
if (JSON.stringify(arr[i]) === JSON.stringify(item)) {
return i;
}
}
return -1;
}
2.数组求和
- 题目描述:
计算给定数组 arr 中所有元素的总和
数组中的元素均为 Number 类型 - 示例:
输入[ 1, 2, 3, 4 ]
输出10
我的方法:
function sum(arr) {
var sum=0;
if(arr.length==0){
return 0;
}
for(i=0;i<arr.length;i++){
sum+=arr[i];
}
return sum;
}
解决方法:
- 不考虑算法复杂度,用递归做
function sum(arr) { var len = arr.length; if(len == 0){ return 0; } else if (len == 1){ return arr[0]; } else { return arr[0] + sum(arr.slice(1)); } }
- 常规循环
本以为应该需要判断数组长度为0或1时的情况,细看原来是function sum(arr) { var s = 0; for (var i=arr.length-1; i>=0; i--) { s += arr[i]; } return s; }
i=arr.length-1; i>=0;
,为0循环不执行,结果为0,长度为1循环会计算arr[0] - 函数式编程 map-reduce
Array.prototype.reduce()
对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
语法:arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
参数:- callback:执行数组中每个值的函数。
包含四个参数:- accumulator:累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(见于下方)。
- currentValue:数组中正在处理的元素。
- currentIndex:可选,数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则为1。
- array:可选,调用reduce()的数组
- initialValue:可选,作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
function sum(arr) { return arr.reduce(function(prev, curr, idx, arr){ return prev + curr; }); }
- callback:执行数组中每个值的函数。
- forEach遍历
Array.prototype.forEach()
对数组的每个元素执行一次提供的函数。
语法:arr.forEach(callback[, thisArg]);
参数:- callback:为数组中每个元素执行的函数。
该函数接收三个参数:- currentValue:数组中正在处理的当前元素。
- index:可选,数组中正在处理的当前元素的索引。
- array:可选,forEach() 方法正在操作的数组。
- thisArg:可选,当执行回调函数时用作 this 的值(参考对象)。
- 返回值:undefined
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
function sum(arr) { var s = 0; arr.forEach(function(val, idx, arr) { s += val; }, 0); return s; };
- callback:为数组中每个元素执行的函数。
- eval
-
eval()函数:会将传入的字符串当做 JavaScript 代码进行执行。
语法:eval(string)
参数:string
一个表示 JavaScript 表达式、语句或一系列语句的字符串。表达式可以包含变量与已存在对象的属性。
返回值:返回字符串中代码的返回值。如果返回值为空,则返回 undefined。 -
Array.prototype.join()方法:
将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。
语法:arr.join([separator])
参数:separator
指定一个字符串来分隔数组的每个元素。如果需要,将分隔符转换为字符串。如果省略(),数组元素用逗号分隔。默认为 “,”。如果separator是空字符串(“”),则所有元素之间都没有任何字符。
返回值:一个所有数组元素连接的字符串。如果 arr.length 为0,则返回空字符串。join() https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/join
eval() https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/evalfunction sum(arr) { return eval(arr.join("+")); };
3.移除数组中的元素(不修改原数组)
- 题目描述:
移除数组 arr 中的所有值与 item 相等的元素。不要直接修改数组 arr,结果返回新的数组 - 示例:
输入[1, 2, 3, 4, 2], 2
输出[1, 3, 4]
我的方法:
function remove(arr, item) {
var array=[];
for(var i=0;i<arr.length;i++){
if(arr[i]!=item){
array.push(arr[i]);
}
}
return array;
}
解决方法:
- splice()。
Array.prototype.splice():通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。splice():https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
注意区分:slice()function remove(arr,item){ var newarr = arr.slice(0); for(var i=0;i<newarr.length;i++){ if(newarr[i] == item){ newarr.splice(i,1); i--; } } return newarr; }
slice():https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
- push()(就是我使用的方法)
- filter()
Array.prototype.filter():创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
function remove(arr,item){ return arr.filter(function(ele){ return ele != item; }) }
4.移除数组中的元素
- 题目描述:
移除数组 arr 中的所有值与 item 相等的元素,直接在给定的 arr 数组上进行操作,并将结果返回 - 示例:
输入[1, 2, 2, 3, 4, 2, 2], 2
输出[1, 3, 4]
我的方法:
function removeWithoutCopy(arr, item) {
for(var i=0;i<arr.length;i++){
if(arr[i]==item){
arr.splice(i,1); //在arr的第i个位置,删除1个元素
i--; //元素删除后,length少1,记得写这一句
}
}
return arr;
}
解决方法:
- splice():我使用的方法(上一题有详解)
- shift(),push()
Array.prototype.shift():从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/shift
function removeWithoutCopy(arr, item) { var n=arr.length; for(var i=0;i<n;i++){ if(arr[0]!==item) arr.push(arr[0]); arr.shift(); } return arr; }
5.添加元素(数组末尾,返回新的数组)
- 题目描述:
在数组 arr 末尾添加元素 item。不要直接修改数组 arr,结果返回新的数组 - 示例:
输入[1, 2, 3, 4], 10
输出[1, 2, 3, 4, 10]
我的方法:
function append(arr, item) {
var array=arr.slice(0);
//本来这里用了var array=arr;不能这样的原因是直接赋值双方引用相等,会改变原数组
array.push(item);
return array;
}
解决方法:
-
我使用的方法
slice() :返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变slice():https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
-
普通的迭代拷贝
var append = function(arr, item) { var length = arr.length, newArr = []; for (var i = 0; i < length; i++) { newArr.push(arr[i]); } newArr.push(item); return newArr; };
-
concat()
concat():方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
var append = function(arr, item) { return arr.concat(item); };
6.删除数组第一个元素 (返回新的数组)
- 题目描述:
删除数组 arr 最后一个元素。不要直接修改数组 arr,结果返回新的数组 - 示例:
输入[1, 2, 3, 4]
输出[1, 2, 3]
我的方法:
function truncate(arr) {
var newArr=arr.slice(0);
newArr.pop();
return newArr;
}
解决方法:
-
slice()+pop()
我的方法:若使用var a = arr,这样赋值双方引用相等,若进行修改,实际仍然修改了原数组。因此需要将原数组复制给一个新的数组,可以通过var a = arr.slice(0);实现。使用pop方法可以删除数组的最后一个元素。 -
slice()(方法1的改进)
拷贝数组:从第0个元素开始到第倒数第一个元素(不包含)为止。function truncate(arr) { return arr.slice(0,-1); }
-
filter()
function truncate(arr) { return arr.filter(function(v,i,ar) { return i!==ar.length-1; }); }
-
push.apply+pop
apply() 调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
function truncate(arr) { var newArr=[]; [].push.apply(newArr, arr); newArr.pop(); return newArr; }
-
join+split+pop
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/split
/*注意:数据类型会变成字符型 arr.join() 返回 1,2,3 arr.join('/') 返回 1/2/3 split(元素)指定分隔符,返回新数组*/ function truncate(arr) { var newArr = arr.join().split(','); newArr.pop(); return newArr; }
-
concat+pop
function truncate(arr) { var newArr = arr.concat(); newArr.pop(); return newArr; }
-
普通的迭代拷贝
function truncate(arr, item) { var newArr=[]; for(var i=0;i<arr.length-1;i++){ newArr.push(arr[i]); } return newArr; }
7.添加元素(数组开头,返回新的数组)
- 题目描述:
在数组 arr 开头添加元素 item。不要直接修改数组 arr,结果返回新的数组 - 示例:
输入[1, 2, 3, 4], 10
输出[10, 1, 2, 3, 4]
我的方法:
function prepend(arr, item) {
var newArr=arr.slice(0);
newArr.unshift(item);
return newArr;
}
解决方法:
-
concat()
function prepend(arr, item) { return [item].concat(arr); }
-
push.apply
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
//apply(thisObj,[argArray]):应用某一对象的一个方法,用另一个对象替换当前对象。实际上是改变函数体内 this 的值 function prepend(arr, item) { var newArr=[item]; [].push.apply(newArr, arr); return newArr; }
-
slice+unshift/splice(我使用的方法)
function prepend(arr, item) { var newArr=arr.slice(0); newArr.unshift(item);//newArr.splice(0,0,item); return newArr; }
unshift(): https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift
-
join+split+unshift/splice
/*注意:数据类型会变成字符型 arr.join() 返回 1,2,3 arr.join('/') 返回 1/2/3 split(元素)指定分隔符,返回新数组*/ function prepend(arr, item) { var newArr=arr.join().split(','); newArr.unshift(item);//newArr.splice(0,0,item); return newArr; }
-
普通的迭代拷贝
function prepend(arr, item) { var newArr=[]; for(var i=0;i<arr.length;i++){ newArr.push(arr[i]); } newArr.unshift(item); return newArr; }
8.删除数组第一个元素(返回新的数组)
- 题目描述:
删除数组 arr 第一个元素。不要直接修改数组 arr,结果返回新的数组 - 示例:
输入[1, 2, 3, 4]
输出[2, 3, 4]
我的方法:
function curtail(arr) {
var newArr=arr.slice(0);
newArr.shift();
return newArr;
}
解决方法:
-
slice()
function curtail(arr) { return arr.slice(1); }
-
filter()
function curtail(arr) { return arr.filter(function(v,i) { return i!==0; }); }
-
join+split+shift
//注意:数据类型会变成字符型 function curtail(arr) { var newArr = arr.join().split(','); newArr.shift(); return newArr; }
-
push.apply+shift
function curtail(arr) { var newArr=[]; [].push.apply(newArr, arr); newArr.shift(); return newArr; }
-
concat+shift
function curtail(arr) { var newArr = arr.concat(); newArr.shift(); return newArr; }
-
普通的迭代拷贝
function curtail(arr) { var newArr=[]; for(var i=1;i<arr.length;i++){ newArr.push(arr[i]); } return newArr; }
9.
————————————————
7.查找重复元素
8.避免全局变量
解释:在Javascript语言中,声明变量使用的都是关键字var,如果不使用var而直接声明变量,则该变量为全局变量。
9.正确的函数定义
解释:else中的语句相当于将if中的function重写,因此无论flag为何值,返回的方法始终为重写后的方法。将方法赋值给一个变量,方法就不会被重写,因此才能得到正确的结果。
10.正确的使用 parseInt
解释:按10进制去处理字符串,碰到非数字字符,会将后面的全部无视。