牛客网js学习总结
来源:互联网 发布:validateform js 编辑:程序博客网 时间:2024/05/16 17:41
- 数组
- 查找数组元素位置
- 数组求和
- 移除数组中的元素 返回新数组
- 移除数组中的元素
- 添加元素
- 删除数组最后一个元素
- 添加元素
- 删除数组第一个元素
- 数组合并
- 添加元素
- 计数
- 查找重复元素
- 求二次方
- 查找元素位置
- 函数
- 定时器计时器
- 函数传参
- 函数的上下文
- 二次封装函数
- 使用 arguments
- Number
- 二进制转换
- 二进制转换
- 二进制转换
- 正则
- 判断是否包含数字
- 检查重复字符串
- 判断是否以元音字母结尾
- 获取指定字符串
- 判断是否符合指定格式
- USD格式
数组
1.查找数组元素位置
找出元素 item 在给定数组 arr 中的位置
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; }
2.数组求和
计算给定数组 arr 中所有元素的总和
不考虑算法复杂度,用递归做:
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)); } }
常规循环:
function sum(arr) { var s = 0; for (var i=arr.length-1; i>=0; i--) { s += arr[i]; } return s; }
函数式编程 map-reduce:
function sum(arr) { return arr.reduce(function(prev, curr, idx, arr){ return prev + curr; }); }
forEach遍历:
function sum(arr) { var s = 0; arr.forEach(function(val, idx, arr) { s += val; }, 0); return s; };
eval:
function sum(arr) { return eval(arr.join("+")); };
3.移除数组中的元素 (返回新数组)
移除数组 arr 中的所有值与 item相等的元素。不要直接修改数组arr,结果返回新的数组
1.splice()
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; }
2.push()
function remove(arr,item){ var newarr = []; for(var i=0;i<arr.length;i++){ if(arr[i] != item){ newarr.push(arr[i]); } } return newarr; } function remove(arr,item){ var newarr = []; for(var i=0;i<arr.length;i++){ if(arr[i] == item)continue; newarr.push(arr[i]); } return nawarr; }
3.Arra y.prototype.filter()
function remove(arr,item){ return arr.filter(function(ele){ return ele != item; }) }
4.移除数组中的元素
移除数组 arr 中的所有值与 item 相等的元素,直接在给定的 arr 数组上进行操作,并将结果返回
function removeWithoutCopy(arr, item) { for(var i=0; i<arr.length; i++) { if(item == arr[i]) { arr.splice(i,1); i--; } } return arr;}
5.添加元素
在数组 arr 末尾添加元素 item。不要直接修改数组 arr,结果返回新的数组
普通的迭代拷贝
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;};
使用slice浅拷贝+push组合
var append2 = function(arr, item) { var newArr = arr.slice(0); // slice(start, end)浅拷贝数组 newArr.push(item); return newArr;};
concat
var append3 = function(arr, item) { return arr.concat(item);};
join+split+push组合
function append(arr, item) { var newArr=arr.join().split(','); newArr.push(item); return newArr;}
使用unshift.apply
function append(arr, item) { var newArr=[item]; [].unshift.apply(newArr, arr); return newArr;}
6.删除数组最后一个元素
删除数组 arr 最后一个元素。不要直接修改数组 arr,结果返回新的数组
利用slice
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
function truncate(arr) { var newArr=[]; [].push.apply(newArr, arr); newArr.pop(); return newArr;}
利用join+split+pop 注意!!!:数据类型会变成字符型
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,结果返回新的数组
利用concat
function prepend(arr, item) { return [item].concat(arr);}
使用push.apply
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;}
使用join+split+unshift/splice组合
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,结果返回新的数组
利用slice
function curtail(arr) { return arr.slice(1);}
利用filter
function curtail(arr) { return arr.filter(function(v,i) { return i!==0; });}
利用push.apply+shift
function curtail(arr) { var newArr=[]; [].push.apply(newArr, arr); newArr.shift(); return newArr;}
利用join+split+shift 注意!!!:数据类型会变成字符型
function curtail(arr) { var newArr = arr.join().split(','); 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.数组合并
合并数组 arr1 和数组 arr2。不要直接修改数组 arr,结果返回新的数组
//利用concat
function concat(arr1, arr2) { return arr1.concat(arr2);}
//利用slice+push.apply
function concat(arr1, arr2) { var newArr=arr1.slice(0); [].push.apply(newArr, arr2); return newArr;}
//利用slice+push
function concat(arr1, arr2) { var newArr=arr1.slice(0); for(var i=0;i<arr2.length;i++){ newArr.push(arr2[i]); } return newArr;}
//普通的迭代拷贝
function concat(arr1, arr2) { var newArr=[]; for(var i=0;i<arr1.length;i++){ newArr.push(arr1[i]); } for(var j=0;j<arr2.length;j++){ newArr.push(arr2[j]); } return newArr;}
10.添加元素
在数组 arr 的 index 处添加元素 item。不要直接修改数组 arr,结果返回新的数组
//利用slice+concat
function insert(arr, item, index) { return arr.slice(0,index).concat(item,arr.slice(index));}
//利用concat +splice
function insert(arr, item, index) { var newArr=arr.concat(); newArr.splice(index,0,item); return newArr;}
//利用slice+splice
function insert(arr, item, index) { var newArr=arr.slice(0); newArr.splice(index,0,item); return newArr;}
//利用push.apply+splice
function insert(arr, item, index) { var newArr=[]; [].push.apply(newArr, arr); newArr.splice(index,0,item); return newArr;}
//普通的迭代拷贝
function insert(arr, item, index) { var newArr=[]; for(var i=0;i<arr.length;i++){ newArr.push(arr[i]); } newArr.splice(index,0,item); return newArr;}
11.计数
统计数组 arr 中值等于 item 的元素出现的次数
//filter()–>利用指定的函数确定是否在返回的数组中包含某一项
function count(arr, item) { var count = arr.filter(function(a) { return a === item; //返回true的项组成的数组 }); return count.length; }
//filter()
function count(arr, item) { return arr.filter(function(a){ return (a==item); }).length}
//map()–>对数组中的每一项进行给定函数,返回每次函数条用的结果组成的数组;
function count(arr, item) { var count = 0; arr.map(function(a) { if(a === item) { count++; } }); return count;}
//for循环
function count(arr, item) { var count = 0; for(var i=0; i<arr.length; i++) { if(arr[i] === item) { count++; } } return count;}
//reduce()–>从数组的第一项开始,逐个遍历到最后;
function count(arr, item) { var count = arr.reduce(function(prev, curr) { return curr === item ? prev+1 : prev; }, 0); return count;}
//forEach()–>对数组中的每一项运行传入的函数
function count(arr, item) { var count = 0; arr.forEach(function(a) { a === item ? count++ : 0; }); return count;}
12.查找重复元素
找出数组 arr 中重复出现过的元素
先排序然后再判断。先排序,如果后一个与前一个相等且未保存,则保存。
function duplicates(arr) { var new_arr = arr.sort();//先把arr排序 var res = [] ;//目标容器 for( var i = 0 ; i < new_arr.length ; i++){ if(new_arr[i] == new_arr[i+1] && new_arr[i] !=new_arr[i-1]){//判断是否重复,是否已经放入容器 res.push(new_arr[i]); } }return res;
上一个改写,for in循环
function duplicates(arr) { var a=arr.sort(),b=[]; for(var i in a){ if(a[i]==a[i-1] && b.indexOf(a[i])==-1) b.push(a[i]); } return b;}
判断索引位置
如果elem的第一个索引和最后一个的索引不一样,说明这个值重复.
在结果数组中这个值不存在,就把这个值添加进去
function duplicates(arr) { var result = []; arr.forEach(function(elem){ if(arr.indexOf(elem) !=arr.lastIndexOf(elem) && result.indexOf(elem) == -1){ result.push(elem); } }); return result;}
计数排序
function duplicates(arr) { //声明两个数组,a数组用来存放结果,b数组用来存放arr中每个元素的个数 var a = [],b = []; //遍历arr,如果以arr中元素为下标的的b元素已存在,则该b元素加1,否则设置为1 for(var i = 0; i < arr.length; i++){ if(!b[arr[i]]){ b[arr[i]] = 1; continue; } b[arr[i]]++; //b[arr[i]]= b[arr[i]]?b[arr[i]]+1:1;//等同于上面的if语句 } //遍历b数组,将其中元素值大于1的元素下标存入a数组中 for(var i = 0; i < b.length; i++){ if(b[i] > 1){ a.push(i); } } return a; }
使用对象,不会有当值很大时这种方案出现的浪费大量空间的情况
function duplicates(arr) { var obj = {}; var result = []; //遍历数组,将数组的值作为obj的索引,出现次数为值 arr.forEach(function(item){ if(obj[item]){ obj[item] +=1; }else{ obj[item] = 1; } }); //获取对象自身属性 var propertyNames = Object.getOwnPropertyNames(obj); //遍历对象,将重复出现的元素取出 propertyNames.forEach(function(item){ if(obj[item] > 1){ result.push(parseInt(item)); } }); return result; }
13.求二次方
为数组 arr 中的每个元素求二次方。不要直接修改数组 arr,结果返回新的数组
map
function square(arr) { return arr.map(function(item,index,array){ return item*item; //return Math.pow(item,2); })}
遍历原数组,将其每一个元素求平方,然后存入新的数组即可。
forEach
function square(arr) { //声明一个新的数组存放结果 var a = []; arr.forEach(function(e){ //将arr中的每一个元素求平方后,加入到a数组中 a.push(e*e); }); return a; }
普通for循环
function square(arr) { var newArr = []; for(var i=0;i<arr.length;i++){ newArr.push(arr[i]*arr[i]); //newArr[i] = Math.pow(arr[i],2); } return newArr;}
14.查找元素位置
在数组 arr 中,查找值与 item 相等的元素出现的所有位置
//filter
function findAllOccurrences(arr, target) { var result=[]; arr.filter(function(item,index){ return item===target&&result.push(index); }); return result;}
//for
function findAllOccurrences(arr, target) { var result=[]; for(var i=0;i<arr.length;i++){ if(arr[i]===target){ result.push(i); } } return result;}
//lastIndexOf+slice/splice
function findAllOccurrences(arr, target) { var result=[],index=arr.lastIndexOf(target); while(index>-1){ result.push(index); arr.splice(index,1);//arr=arr.slice(0,index); index=arr.lastIndexOf(target); } return result;}
//indexOf
function findAllOccurrences(arr, target) { var result=[],index=arr.indexOf(target); while(index>-1){ result.push(index); index=arr.indexOf(target,index+1); } return result;}
使用map和filter
function findAllOccurrences(arr, item) { return arr.map(function(e, index) { return e === item ? index : -1; /* 样例返回结果为[ -1, -1, -1, -1, -1, -1, -1, 0, 6 ] */ }).filter(function(i) { return i !== -1; /* 过滤掉 i === -1 的情况 */ })}
函数
1.定时器计时器
1、从 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一个数字,每次数字增幅为 1
2、返回的对象中需要包含一个 cancel 方法,用于停止定时操作
3、第一个数需要立即输出
一、通过setInterval()方法
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); } }; }
二、通过setTimeout()方法【出自 @shawnan】
function count(start, end) { if(start <= end){ console.log(start); start++; st = setTimeout(function(){count(start, end)}, 100); } return { cancel: function(){clearTimeout(st);} }}
函数传参
将数组 arr 中的元素作为调用函数 fn 的参数
function argsAsArray(fn, arr) { return fn.apply(this, arr); }
函数的上下文
将函数 fn 的执行上下文改为 obj 对象
//三种方案
//apply
function speak(fn, obj) { return fn.apply(obj);}
//call
function speak(fn, obj) { return fn.call(obj);}
//bind
function speak(fn, obj) { return fn.bind(obj)();}
二次封装函数
已知函数 fn 执行需要 3 个参数。请实现函数 partial,调用之后满足如下条件:
1、返回一个函数 result,该函数接受一个参数
2、执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致
// call和apply必须显式地调用str3,立即执行
// bind不是立即执行,未传入str3时,并未执行,只是返回一个函数,等待参数传入
// this用于上下文不确定的情况
// call
function partial(fn, str1, str2) { function result(str3) { return fn.call(this, str1, str2, str3); } return result;}
// apply(这里只是为了对照)
function partial(fn, str1, str2) { function result(str3) { return fn.apply(this, [str1, str2, str3]); } return result;}
// 这个bind会生成一个新函数(对象), 它的str1, str2参数都定死了, str3未传入, 一旦传入就会执行
function partial(fn, str1, str2) { return fn.bind(this, str1, str2); // 或 return fn.bind(null,str1,str2);}
// bind同上, 多了一步, 把str3传入的过程写在另一个函数里面,
// 而另一个函数也有str1, str2参数
// 此法有种多次一举的感觉,但是表示出了后续的调用。
function partial(fn, str1, str2) { function result(str3) { return fn.bind(this, str1, str2)(str3); } return result;}
// 匿名函数,默认this绑定global,与bind的第一个参数为this时效果一样。
function partial(fn, str1, str2) { return function(str3) { return fn(str1, str2, str3); }}
// ES6。this指向undefined.
const partial = (fn, str1, str2) => str3 => fn(str1, str2, str3);
使用 arguments
函数 useArguments 可以接收 1 个及以上的参数。请实现函数 useArguments,返回所有调用参数相加后的结果。本题的测试参数全部为 Number 类型,不需考虑参数转换。
常规解法
function useArguments() { var result; for(var i=0;i<arguments.length;i++){ result += arguments[i]; } return result;}
转化数组
function useArguments() { return Array.prototype.reduce.call(arguments,function(prev,curr){ return prev + curr; });}
Number
二进制转换
获取数字 num 二进制形式第 bit 位的值。注意:
1、bit 从 1 开始
2、返回 0 或 1
3、举例:2 的二进制为 10,第 1 位为 0,第 2 位为 1
通过num.toString(2)能直接将num转换为2进制数格式的字符串,利用下标就能将对应值取出来。题目返回的数字是从右往左,因此下标为倒数。
function valueAtBit(num, bit) { var s = num.toString(2); return s[s.length - bit]; }
//
function valueAtBit(num, bit) { //toString转化为二进制,split将二进制转化为数组,reverse()将数组颠倒顺序 var arr = num.toString(2).split("").reverse(); return arr[bit-1];}
二进制转换
给定二进制字符串,将其换算成对应的十进制数字
function base10(str) { /** 其它进制转十进制 parseInt(str,2) parseInt(str,8) parseInt(str,16) */ return parseInt(str,2);}
二进制转换
将给定数字转换成二进制字符串。如果字符串长度不足 8 位,则在前面补 0 到满8位。
首先通过toString方法将num转为2进制数形式,然后判断其长度是否足够8位。如不足8位,则声明一个“0000000”字符串用于补0,因为目标的2进制数形式最少为一位,因此最多只需要7个0;通过slice方法对“0000000”进行截取,然后将其结果加在目标前面即可。
function convertToBinary(num) { //转换为2进制格式 var s = num.toString(2); //获得2进制数长度 var l = s.length; if(l<8){ //声明一个字符串用于补满0 var s1 = "0000000"; var s2 = s1.slice(0,8-l); s = s2+s; } return s; }
//
function convertToBinary(num) { var str = num.toString(2); while(str.length < 8) { str = "0" + str; } return str;}
//
function convertToBinary(num) { return ('00000000' + num.toString(2)).slice(-8);}
//
function convertToBinary(num) { return ('00000000'+num.toString(2)).substr(-8);}
转为二进制后,先除以10的8次方,然后取小数点后的数
function convertToBinary(num) { var toBit = num.toString(2); return ( toBit / Math.pow(10, 8) ).toFixed(8).substr(2);}function convertToBinary(num) { var str=num.toString(2).split(''); while(str.length<8){ str.unshift(0); } return str.join('');}
正则
判断是否包含数字
给定字符串 str,检查其是否包含数字,包含返回 true,否则返回 false
function containsNumber(str) { var b = /\d/; return b.test(str); }
//
function containsNumber(str) { for(var i=0;i<10;i++){ if(str.indexOf(i)!=-1){ return true; } } return false;}
//
function containsNumber(str) { for(var i=0;i<str.length;i++){ if(Number(str[i])){ return true; } } return false;}
/只要匹配到一个数字,就返回true/
function containsNumber(str) { var pattern=/\d/g; if(str.match(pattern)) return true; else return false;}
检查重复字符串
给定字符串 str,检查其是否包含连续重复的字母(a-zA-Z),包含返回true,否则返回 false
在正则表达式中,利用()进行分组,使用斜杠加数字表示引用,\1就是引用第一个分组,\2就是引用第二个分组。将[a-zA-Z]做为一个分组,然后引用,就可以判断是否有连续重复的字母。
function containsRepeatingLetter(str) { return /([a-zA-Z])\1/.test(str); }
//
function containsRepeatingLetter(str) { var pattern = /[a-zA-Z]/g; for(var i=0;i<str.length;i++){ if(str[i]==str[i+1] && pattern.test(str[i])){ return true; } } return false;}
判断是否以元音字母结尾
给定字符串 str,检查其是否以元音字母结尾
1、元音字母包括 a,e,i,o,u,以及对应的大写
2、包含返回 true,否则返回 false
首先确定元音集合[a,e,i,o,u],然后是以元音结尾,加上
function endsWithVowel(str) { return /[a,e,i,o,u]$/i.test(str); }
获取指定字符串
给定字符串 str,检查其是否包含 连续3个数字
1、如果包含,返回最新出现的 3 个数字的字符串
2、如果不包含,返回 false
function captureThreeNumbers(str) { //声明一个数组保存匹配的字符串结果 var arr = str.match(/\d{3}/); //如果arr存在目标结果,则返回第一个元素,即最早出现的目标结果 if(arr) return arr[0]; else return false; //return arr? arr[0]:false; if语句可用这个代替 }
判断是否符合指定格式
给定字符串 str,检查其是否符合如下格式
1、XXX-XXX-XXXX
2、其中 X 为 Number 类型
本题需要注意格式,开头^和结尾
function matchesPattern(str) { return/^(\d{3}-){2}\d{4}$/.test(str);}
USD格式
给定字符串 str,检查其是否符合美元书写格式
1、以
首先,开头必是
然后$后必然接数字,并且最少一位,最多三位数,可用{m,n}表示,最少m位,最多n位,因此此段为\d{1,3}
接着,后面如还有数,则必然有,分隔,并且后面必有3个数,类似于,XXX的格式会出现0或者n次,因此此段可表示为(,\d{3})*
最后,如有小数部分,则注意对小数点进行转义,此段可表示为(.\d{2})?
因此,最后的正则表达式为/^$\d{1,3}(,\d{3})*(.\d{2})?$/
function isUSD(str) { return /^\$\d{1,3}(,\d{3})*(\.\d{2})?$/.test(str);}
- 牛客网js学习总结
- js扩展学习总结
- js学习总结
- JS学习总结
- JS学习总结
- require.js学习总结
- require.js学习总结
- Ember.js学习总结
- js学习小总结
- js学习阶段总结
- js学习小总结
- js学习总结2
- D3.js学习总结
- js学习总结
- js学习总结
- js学习总结
- JS学习总结
- JS 学习总结
- JS动态获取当前时间戳
- Java笔记--08
- 二. re模块函数详解
- 推荐系统老司机的十条经验
- 如何杀死含有redis的所有进程
- 牛客网js学习总结
- 专业的直播APP音视频互动开发平台
- Linux学习笔记之权限管理
- iOS学习笔记-146.网络06——NSURLConnection03_使用
- Windbg调试win登录用户密码验证过程
- Nginx编译安装及相关功能实现
- 推荐系统之眼
- C#中的局部变量冲突
- 面试的几个总结