js数组获取index_牛客网45道JS能力测评经典题总结

 是新朋友吗?记得先点web前端学习圈关注我哦~

cc17cf82eb2b0437c81048f998354c8f.png

前言

牛客网的45道JS能力评测题,个人觉得是非常好的45道 js 基础检测题,基本就是对自己的JavaScript基础做一个比较全面的评估,包括if语句、循环体、基础操作符、setInterval、setTimeout、流程控制、常用数组方法及es6相关(解构、Map、Set、...等)。之前我已经做过一遍了,我记得以前牛客网不支持es6的写法,这两天花了点时间把所有题目又做了一遍,发现支持es6了。这次每个题目我都尽力用了不同的方法实现,建议各位看官收藏,需要的时候方便查看。当然如果你有更好更新颖的实现方法,欢迎评论区留言交流。

dc5d186a72ed2aab6a3baae9a67e98a3.png

我也把常用的数组方法和字符串方法贴在这里,可以自测掌握程度

771683c6b28a63844f5ffa29a20ec37b.png8e8f2e3896d5b504f96e85a9697077ea.png1、查找数组元素位置

1706a2f24960bc8d253dd46dd6b642d2.png

第一题比较简单,就直接上答案:

// 方法一

这里顺便说一下Array.prototype.indexOf

indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。

语法:

 arr.indexOf(searchElement) //查找searchElement元素在数组中的第一个位置
 arr.indexOf(searchElement[, fromIndex = 0]) //从fromIndex开始查找searchElement元素在数组中的第一个位置

还有另外一个查找字符串的方法String.prototype.indexOf()

str.indexOf(searchValue[, fromIndex])
  • searchValue:一个字符串表示被查找的值。
  • fromIndex (可选):表示调用该方法的字符串中开始查找的位置。可以是任意整数。默认值为 0。如果 fromIndex < 0 则查找整个字符串(如同传进了 0)。如果 fromIndex >= str.length,则该方法返回 -1,除非被查找的字符串是一个空字符串,此时返回 str.length。

具体可以看看👉MDN

2、添加元素(末尾添加)

daaacabc1b4b8069582f47edf05c9300.png方法一:普通的for循环拷贝+push

function append(arr, item) {

方法二:使用concat将传入的数组或非数组值与原数组合并,组成一个新的数组并返回

function append(arr, item) {

方法三:使用slice浅拷贝+push

function append(arr, item) {

方法四:...扩展运算符如果不知道的,可以看看es6的相关知识

function append(arr, item) {

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

03f91cab0b378d84689c2adc62359233.png这里需要注意理解题目,是直接操作原数组,所以不能出现newArr

方法一:普通for循环+splice

function removeWithoutCopy(arr, item) {

方法二:方法一的另外一种写法

在这里要注意在删除掉一个元素时,要 i–,即删除这个元素后,其他元素位置往前移。

function removeWithoutCopy(arr, item) {

把第3题稍微变一下,看下一题

4、移除数组中的元素(返回新的数组)

3a08485b8c202f2b6c50393f0e877aba.png方法一:filter过滤

function remove(arr, item) {

方法二:for循环+push

function remove(arr, item) {

方法三:forEach+push(效率高于for循环)

function remove(arr, item) {

方法四:for循环+splice

function remove(arr,item){

5、数组求和

d92dfa5b45a7fa2ab41a9bd39fc451c0.png

方法一:普通for循环

function sum(arr) {

方法二:forEach循环

function sum(arr) {

方法三:reduce

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值,具体可以看看es6相关知识。

function sum(arr) {

方法四:eval

eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。

function sum(arr) {

6、删除数组最后一个元素

02c3e3c120ef97bd83a7075a89f4be67.png方法一:slice

function truncate(arr) {

方法二:concat/slice+pop

function truncate(arr) {

7、添加元素(开头添加)

ac5f2bd1b7848ceb67d1fe07c514b25b.pngconcat/slice/arr.join().split(',')+unshift

function prepend(arr, item) {

8、删除数组第一个元素

7b5f0f7049ccedee208f01947b344688.png与第7题大同小异,玩不出太多花样,如你有其他好玩的方法,欢迎留言

function curtail(arr) {

9、合并数组

1156eee051a6c3d7a997c08232351c7a.png方法很多,欢迎大佬们留言评论方法一:concat

function concat(arr1, arr2) {

方法二:...扩展运算符

function concat(arr1, arr2) {

方法三:slice+push.apply

function concat(arr1, arr2) {

10、添加元素(指定位置添加)

3ac68b68fe1998f94bd0449b8d3a121c.png方法一:先复制前0~index个元素,将item元素插入之后,再拼接index之后的元素

function insert(arr, item, index) {

方法二:使用splice方法插入(效率较高)

function insert(arr, item, index) {

方法三:push.apply+splice

function insert(arr, item, index) {

11、计数

6aa7f6243cfc0b9cf0b884b8aeccedc6.png方法一:普通for循环

function count(arr, item) {

方法二:forEach

function count(arr, item) {

方法三:filter

function count(arr, item) {

方法四:map(效率高于filter)

function count(arr, item) {

map函数和filter有点像,但是map是对数组中的所有元素进行复核函数条件的处理,最终得到的是一个新数组,元素个数不变。

filter函数虽然也是返回一个新数组,但是元素的个数等于复核函数条件的元素总和。

方法五:reduce

function count(arr, item) {

12、查找重复元素

cdfbcd20b0ba609baf69bf280bad03fb.png方法一:for/for in/+sort先进行排序,然后判断排序之后的前一个数据是否等于后一个数据,如果是且结果数组没有这个元素

//for 运行时间:1596ms 占用内存:77772k

方法二:forEach利用索引判断是否重复(使用了两次)

// 运行时间:1184ms 占用内存:77772k

方法三:reduce先判断数组中元素出现的次数,如果大于1并且结果数组之前无此元素,则将这个元素放到结果数组中

// 运行时间:1129ms 占用内存:77776k
function duplicates(arr) {
   let b = [];
   let resArr = [];
   for (let i= 0; i        b[i] = arr.reduce( (init,curr)=> {
        //如果当前置等于item,该函数值加一
           return curr === arr[i] ? init+1:init;
           },0)
           if (b[i] > 1 && resArr.indexOf(arr[i]) === -1){
               resArr.push(arr[i]);
           }
        }
    return resArr;
}

13、求二次方

d216fa4d9748645cf594afc7477cef8d.png方法一:for/forEach

// 运行时间:1466ms 占用内存:77772k

方法二:map

// 运行时间:1433ms 占用内存:78004k

14、查找元素位置

18b42d74c5495c0e101584025b783c5d.png方法一:for

//运行时间:1139ms 占用内存:77772k

方法二:forEach

// 运行时间:1135ms 占用内存:77776k

15、避免全局变量

c4849be5cff1d870b2de628171a73039.png原代码:

function globals() {

修复:

function globals() {

16、正确的函数定义

79c74eb889e59c6351fbcb30f60d7286.png原代码:

function functions(flag) {

修复:else中的语句相当于将if中的function重写,因此无论flag为何值,返回的方法始终为重写后的方法。将方法赋值给一个变量,方法就不会被重写,因此才能得到正确的结果。并且只能用var声明。

function functions(flag) {

17、正确的使用 parseInt

c2a65d263f1da9962a339f96560a539c.png原代码:

function parse2Int(num) {

修复:parseInt(string, radix) 函数可解析一个字符串,并返回一个整数。参数 radix 表示要解析的数字的基数。该值介于 2 ~ 36 之间。如果省略该参数或其值为 0,parseInt() 会根据 string 来判断数字的基数。举例,如果 string 以 “0x” 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。而本题则是要求解析为十进制的整数。

function parse2Int(num) {

注意:

1.只有字符串中的第一个数字会被返回。

2.如果字符串的第一个字符不能被转换为数字,那么 parseFloat() 会返回 NaN。3.如果参数 radix 小于 2 或者大于 36,则 parseInt() 将返回 NaN。

18、完全等同

3860e07aec81601e8a34844aa5e0ccfc.png

function identity(val1, val2) {

19、计时器

e0dfcb8ab28fcfeefabaa5f95b3c10fd.png

function count(start, end) {

setInterval(code,millisec) 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。

code 是要调用的函数或要执行的代码串,millisec 是周期性执行或调用 code 之间的时间间隔,以毫秒计。

setInterval() 方法会不停地调用 code 函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。clearInterval() 方法可取消由 setInterval() 设置的 timeout,其中的参数必须是由 setInterval() 返回的 ID 值。

20、流程控制

5a8da794eeb6fa412baf7ad6c1118da5.png

function fizzBuzz(num) {

21、函数传参

cd5ac1d6e5c61a9b91d5acdbd922dddf.png方法一:apply/call

function argsAsArray(fn, arr) {

function.apply(newObj[, argsArray]) 方法可以修改指定函数的调用对象。function 是调用对象将被修改的函数,newObj 是函数的新调用对象,argsArray 是传递给function函数的参数,数组或者arguments对象。

apply 方法是将传递给函数的参数放入一个数组中,传入参数数组即可。

function.call(newObj[, arg1[, arg2[, [,…argN]]]]) 方法的作用和 apply() 方法类似,只有一个区别,就是 call() 方法接受的是若干个参数的列表,而 apply() 方法接受的是一个包含多个参数的数组。

方法二:...扩展运算符

function argsAsArray(fn, arr) {

22、函数的上下文

d9f67539c8022b2e26510a1fd590205a.png这个题目考察的是改变this指向

//apply

23、返回函数

c62c2b2798b642d7e54a56218ff2b201.png

function functionFunction(str) {

24、使用闭包

960d240b00b3cadb621afd45aa11a0de.png

function makeClosures(arr, fn) {

25、二次封装函数

a59d6aee86abb6ce5df05000aca89143.png因为没有要求函数内部this指向和作用域,所以可以不用 call 和 apply 方法。

function partial(fn, str1, str2) {

26、使用 arguments

6b08e477fd406084b392a6769ac52adf.png方法一:eval

function useArguments() {

方法二:reduce+call组合

function useArguments() {

27、使用 apply 调用函数

120d24bbfc3ca171e1115d456e9c841f.png21题已经讲过,不再赘述

function callIt(fn) {

28、二次封装函数

8b1061ef4e593ace7d5ef02c562cda03.png注意与25题的要求区别。入门级别,不多说,是个人都会

function partialUsingArguments(fn) {

29、柯里化

aa5fcba23f313bd24617438d940bd927.png柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。

function curryIt(fn) {

30、或运算

31fa74cd638b641e74c4e6fc832c150f.png

function or(a, b) {

31、且运算

17d5ab2512b0761c41fdaa3c68f32e08.png

function and(a, b) {

32、模块

ab35a2b3b2d59ff0676cfcefcba933a4.png
function createModule(str1, str2) {

33、二进制转换(十进制转二进制)

682341c95b1302686d2a2c6f978024f6.png

function valueAtBit(num, bit) {

NumberObject.toString(radix) 方法可把一个 Number 对象转换为一个字符串,并返回数字的字符串表示。radix 表示数字的基数,为 2 ~ 36 之间的整数。若省略该参数,则默认使用基数 10。例如,当 radix 为 2 时,NumberObject 会被转换为二进制值表示的字符串。

当调用该方法的对象不是 Number 时抛出 TypeError 异常。

通过num.toString(2)能直接将num转换为2进制数格式的字符串,利用下标就能将对应值取出来。题目返回的数字是从右往左,因此下标为倒数。

34、二进制转换(二进制转十进制)

259996649c08b764af54a1f33e924543.png

function base10(str) {

35、二进制转换(十进制转8位二进制)

3e879857334933d3bd06bb9162ee72aa.png

function convertToBinary(num) {

36、乘法

9bc71ce4fd6713c67a1dc4d51627c3fe.png本题要注意题目要求,我们需要考虑精度,且保证以小数点后位数多的为准。以下写法是不能通过的

// 这种写法是通不过的

正解:

function multiply(a, b) {
  • toFixed(num):toFixed() 方法可把 Number 四舍五入为指定小数位数的数字; 参数num: 代表小数位数;
let num = 
  • parseFloat(string): parseFloat()函数可解析一个字符串,并返回一个浮点数;参数 string 可为数字可为字符串,当参数为字符串时,判断个字符是否是数字,如果是,则对字符串进行解析,直到到达数字的末端为止,然后以数字返回该数字,如果不是,返回NAN;
parseFloat(

37、改变上下文

81dc3e0618512fdcc20ba1949f90f1ba.png前面有讲过,不再赘述

function alterContext(fn, obj) {

38、批量改变对象的属性

d788f65853e26a53867635e9947c23da.png

function alterObjects(constructor, greeting) {

prototype 属性可以向对象添加属性和方法。这是原型链的知识:当查找一个对象的方法或者是属性时,首先会在该对象中寻找,如果找到则返回如果实例对象自身不存在该属性,则沿着原型链往上一级查找,找到时则输出,不存在时,则继续沿着原型链往上一级查找,直至最顶级的原型对象Object.prototype,如还是没找到,则返回undefined

将 constructor 的所有实例的 greeting 属性指向给定的 greeting 变量,只需要在constructor的原型上面添加greeting属性,并指定值。关于原型链可以看看我之前的文章:👉「前端料包」深入理解JavaScript原型和原型链

39、属性遍历

5afab09aad863fc27dbc4fbce34ab071.png方法很多凡是有遍历功能的方法都可以

方法一:for in 循环

//运行时间:1148ms 占用内存:77864k

所有继承了 Object 的对象都会继承到 hasOwnProperty() 方法。obj.hasOwnProperty(prop)方法会返回一个布尔值,指示对象 obj 自身属性中是否具有指定的属性 prop 。这个方法可以用来检测一个对象是否含有特定的自身属性,并忽略掉那些从原型链上继承到的属性。

方法二:map

//运行时间:1133ms 占用内存:77828k

Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。方法三:forEach

//运行时间:1173m  占用内存:77872k

最后5题大部分可以用正则表达式实现,关于正则表达式可以看看👉正则表达式不要背

40、判断是否包含数字

480542dbcfb82a2b7dc1becd2f2b6ff0.png方法一:正则test/match

function containsNumber(str) {

方法二:遍历

function containsNumber(str) {

当然如果想折腾,还有纯js判断:

方法三:for循环+charCodeAt()

function containsNumber(str) {

方法四:for循环+Number()

function containsNumber(str) {

41、检查重复字符串

a18bdf56217a7bc4a4e0cc0e123688f5.png

function containsRepeatingLetter(str) {

在正则表达式中,利用()进行分组,使用斜杠加数字表示引用,\1就是引用第一个分组,\2就是引用第二个分组。将[a-zA-Z]做为一个分组,然后引用,就可以判断是否有连续重复的字母。

方法二:字符串方法

function containsRepeatingLetter(str) {

42、判断是否以元音字母结尾

93bf7f7fa4d8cd4ecfd755093771142c.png首先确定元音集合[a,e,i,o,u],然后是以元音结尾,加上 $ ,最后通配大小写,加上i。

function endsWithVowel(str) {

或者简单粗暴:

function endsWithVowel(str) {

43、获取指定字符串

6b97d9250089d9344a7c2a700f3bdaff.png

function captureThreeNumbers(str) {

44、判断是否符合指定格式

f0b5f83d70b4dd70445cba637f581769.png

function matchesPattern(str) {
本题需要注意格式,开头 ^ 和结尾 $ 必须加上来限定字符串,3个数可表示为\d{3},4个数则为\d{4},{n}表示前面内容出现的次数。正则表达式可写作 /^ \d{3}-\d{3}-\d{4}$ / ,有相同部分\d{3}-,因此也可写作 /^(\d{3}-){2}\d{4}$/ 。

45、判断是否符合 USD 格式

f40eb16a749f9a4372b2f19241bb94b4.png

function isUSD(str) {
? 匹配前面一个表达式0次或者1次。等价于 {0,1}。
例如,/e?le?/ 匹配 'angel' 中的 'el',和 'angle' 中的 'le' 
(注意第二个 ? 前面的匹配表达式是 e 而不是 le) 以及 'oslo' 中的'l'。

如果紧跟在任何量词 *、 +、? 或 {} 的后面,将会使量词变为非贪婪的(匹配尽量少的字符),和缺省
使用的贪婪模式(匹配尽可能多的字符)正好相反。
例如,对 "123abc" 应用 /\d+/ 将会返回 "123",如果使用 /\d+?/,那么就只会匹配到 "1"。
还可以运用于向前断言 正向肯定查找x(?=y) 和 正向否定查找x(?!y) 。

* 匹配前一个表达式0次或多次。等价于 {0,}。
例如,/bo*/会匹配 "A ghost boooooed" 中的 'booooo' 和 "A bird warbled" 中的 'b', 
但是在 "A goat grunted" 中将不会匹配任何东西。

. (小数点)匹配  除了换行符(\n)之外的任何单个字符。
例如, /.n/将会匹配"nay, an apple is on the tree"中的'an'和'on', 但是不会匹配 'nay'。

源自:https://juejin.im/post/5f032fe3f265da22c75734b8

声明:文章著作权归作者所有,如有侵权,请联系小编删除。

感谢 · 转发欢迎大家留言

6f012b5b8e67024d7dad5a89078f5ee8.png

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值