目录
- 两个变量数值交换(a与b交换)
- 计算给定数组 arr 中所有元素的总和 (数组中的元素均为 Number 类型)
- 移除数组 arr 中的所有值与 item 相等的元素。不要直接修改数组 arr,结果返回新的数组
- 合并数组 arr1 和数组 arr2。不要直接修改数组 arr,结果返回新的数组
- JS找出数组 arr 中重复出现过的元素
- 编写一个函数, 判断一个数是不是质数(素数)
- 数组去重
- 实现数组扁平化
- js实现数组乱序
- js实现深拷贝
- 持续更新中。。。
1. 两个变量数值交换(a与b交换)
方法一:
var a = 123;
var b = 456;
var c = a;
a = b;
b = c;
方法二:
var a = 123;
var b = 456;
a = a + b;
b = a - b;
a = a - b;
2. 计算给定数组 arr 中所有元素的总和 (数组中的元素均为 Number 类型)
方法一:
function sum(arr) {
var sum = 0;
for (var i=0; i<arr.length; i++) {
sum += arr[i];
}
return sum;
}
console.log(sum([1,2,3,4])); // 10
方法二:
function sum(arr) {
return eval(arr.join('+'));
};
console.log(sum([1,2,3,4])); // 10
3. 移除数组 arr 中的所有值与 item 相等的元素。不要直接修改数组 arr,结果返回新的数组
方法一: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;
}
console.log(remove([1,2,3,4,2],2));//[1,3,4]
方法二:splice
function remove(arr, item) {
var newArr=arr.slice(0); // slice 纯函数 拷贝一份arr数组到newArr
for(var i=0;i<arr.length;i++){
if(newArr[i]==item){
newArr.splice(i,1); //splice 非纯函数 剪去相同的元素
i--;
}
}
return newArr;
}
console.log(remove([1,2,3,4,2],2));//[1,3,4]
关于slice和splice,详情在前端JS初级面试题一第7题
方法三:Array.prototype.filter()
function remove(arr, item) {
return arr.filter(function(ele){
return ele!=item;
});
}
console.log(remove([1,2,3,4,2],2)); //[1,3,4]
4. 合并数组 arr1 和数组 arr2。不要直接修改数组 arr,结果返回新的数组
方法一:纯函数concat 等
function concat(arr1, arr2) {
return arr1.concat(arr2);
}
console.log(concat([1,2,3],[4,5,6])); // [1, 2, 3, 4, 5, 6]
方法二:普通的循环赋值
5. JS找出数组 arr 中重复出现过的元素
方法一:
先对数组进行排序,判断前一个与后一个相等且没有保存的情况下,再把元素放到数组中去。
function duplicates(arr) {
var newArr=[];
arr.sort();
for(var i =0;i<arr.length;i++){
if(arr[i]==arr[i+1]&&(newArr.indexOf(arr[i])==-1) ){
newArr.push(arr[i]);
i++;
}
}
return newArr;
}
console.log(duplicates([1,2,3,2,7,1])) // [1, 2]
方法二:
循环数组,将每个元素与后面的元素相比较,相同且新数组里没有的则push进新数组
function duplicates(arr) {
var a=[];
for(var i=0;i<arr.length-1;i++) {
for(var j=i+1;j<arr.length;j++) {
if(arr[i]==arr[j]&&a.indexOf(arr[i])==-1) {
a.push(arr[i]);
}
}
}
return a.sort();
}
console.log(duplicates([1,2,3,2,7,1])) // [1, 2]
方法三:
循环数组,计算每个元素的个数。最后将个数超过1的元素push进新数组
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数组,将其中元素值大于1的元素下标存入a数组中
for(var i = 0; i < b.length; i++){
if(b[i] > 1){
a.push(i);
}
}
return a;
}
console.log(duplicates([1,2,3,2,7,1])) // [1, 2]
方法四:
循环数组,使用indexOf,lastIndexOf来判断元素是否重复
function duplicates(arr) {
var brr = [];
arr.sort(); //原数组排序;
console.log(arr)
while(arr.length > 0){
//当值的第一个index != 最后一个index,即认为该值重复,将其赋予brr数组,并删除arr数组中所有与该值相同的值。
if(arr.indexOf(arr[0]) != arr.lastIndexOf(arr[0])){
brr.push(arr[0]);
arr.splice(arr.indexOf(arr[0]),arr.lastIndexOf(arr[0])+1);
console.log(arr)
}else{//当第一个index = 最后一个index,即该值不重复。直接删除。
arr.shift();
}
}
return brr;
}
console.log(duplicates([1,2,3,2,7,1,2])) // [1, 2]
方法五:
两层for循环,计算相同元素的数量,如果大于1且新数组里没有,则存入新数组
function duplicates(arr) {
var newArr = [];
for(var i=0;i<arr.length;i++){
var count = 0;
for(var j=0;j<arr.length;j++){
if(arr[i]===arr[j]){
count++;
}
}
if(count>1 && newArr.indexOf(arr[i])===-1){
newArr.push(arr[i]);
}
}
return newArr;
}
console.log(duplicates([1,2,3,2,7,1,2])) // [1, 2]
6. 编写一个函数, 判断一个数是不是质数
又称素数,指整数 在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。
方法一:
function zhishu(n) {
var count = 0;
for (var i = 1; i <= n; i++) {
if (n % i == 0) {
count++
}
}
if (count <= 2) { //是质数
return true;
} else { //不是质数
return false;
}
}
console.log(zhishu(3),zhishu(12)) // true false
方法二:
function zhishu(n) {
//假设是质数
var flag = true;
//从2-(n-1)中,如若能找到一个被n整除的数,说明n不是质数
for (var i = 2; i < n; i++) {
if (n % i == 0) {
flag = false;
}
}
return flag;
}
console.log(zhishu(3),zhishu(12)) // true false
7. 数组去重
方法总结:
1. 传统方式,遍历元素,挨个比较,去重
2. 利用语法自身键不可重复性
方法一:
// 使用 Set (无序,不能重复)
function unique(arr) {
const set = new Set(arr)
return [...set]
}
var arr = [1,1,'a', 'a','true','true','NaN', 'null',true,true,false,false, undefined,undefined, null,null, NaN, NaN,{},{}];
const res = unique(arr)
console.log(res) // [1, "a", "true", "NaN", "null", true, false, undefined, null, NaN, {…}, {…}]
不考虑兼容性,这种去重的方法代码最少。但是这种方法还无法去掉“{}”空对象。
方法二: 利用indexOf去重
function unique(arr) {
const res = []
arr.forEach(item => {
if (res.indexOf(item) < 0) {
res.push(item)
}
})
return res
}
var arr = [1,1,'a', 'a','true','true','NaN', 'null',true,true,false,false, undefined,undefined, null,null, NaN, NaN,{},{}];
const res = unique(arr)
console.log(res) // [1, "a", "true", "NaN", "null", true, false, undefined, null, NaN, NaN, {…}, {…}]
NaN和{}没有去重
方法三: 利用for嵌套for,然后splice去重(ES5中最常用)
function unique(arr){
for(var i=0; i<arr.length; i++){
for(var j=i+1; j<arr.length; j++){
if(arr[i]==arr[j]){ //第一个等同于第二个,splice方法删除第二个
arr.splice(j,1);
j--;
}
}
}
return arr;
}
var arr = [1,1,'a', 'a','true','true','NaN', 'null',true,true,false,false, undefined,undefined, null,null, NaN, NaN,{},{}];
const res = unique(arr)
console.log(res) // [1, "a", "true", "NaN", "null", false, undefined, NaN, NaN, {…}, {…}]
true,null 没了,NaN,{}没有去重
方法四: 利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对。
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return;
}
arr = arr.sort()
var arrry= [arr[0]];
for (var i = 1; i < arr.length; i++) {
if (arr[i] !== arr[i-1]) {
arrry.push(arr[i]);
}
}
return arrry;
}
var arr = [1,1,'a', 'a','true','true','NaN', 'null',true,true,false,false, undefined,undefined, null,null, NaN, NaN,{},{}];
const res = unique(arr)
console.log(res) // [1, "NaN", NaN, NaN, {…}, {…}, "a", false, "null", null, "true", true, undefined]
NaN、{}没有去重
方法五: 利用对象的属性不能相同的特点进行去重
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return
}
var arrry= [];
var obj = {};
for (var i = 0; i < arr.length; i++) {
if (!obj[arr[i]]) {
arrry.push(arr[i])
obj[arr[i]] = 1
} else {
obj[arr[i]]++
}
}
return arrry;
}
var arr = [1,1,'a', 'a','true','true', 'null',true,true,false,false, undefined,undefined, null,null,NaN, NaN,'NaN', {},{}];
var arr1 = [1,1,'a', 'a','true','true','NaN','null',true,true,false,false, undefined,undefined, null,null,NaN,NaN, {},{}];
console.log(unique(arr)) // [1, "a", "true", "null", false, undefined, NaN, {…}]
console.log(unique(arr1)) // [1, "a", "true", "NaN", "null", false, undefined, {…}]
true,null没了,{}去重了,NaN 与’NaN’ 会相互影响
方法六:
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return
}
var array =[];
for(var i = 0; i < arr.length; i++) {
if( !array.includes( arr[i]) ) {//includes 检测数组是否有某个值
array.push(arr[i]);
}
}
return array
}
var arr = [1,1,'a', 'a','true','true', 'null',true,true,false,false, undefined,undefined, null,null,NaN, NaN,'NaN', {},{}];
console.log(unique(arr)) //[1, "a", "true", "null", true, false, undefined, null, NaN, "NaN", {…}, {…}]
{}没有去重
方法七:
function unique(arr) {
var obj = {};
return arr.filter(function(item, index, arr){
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}
var arr = [1,1,'a', 'a','true','true', 'null',true,true,false,false, undefined,undefined, null,null,NaN, NaN,'NaN', {},{}];
console.log(unique(arr)) // [1, "a", "true", "null", true, false, undefined, null, NaN, "NaN", {…}]
所有的都去重了
方法八:
function unique(arr) {
return arr.filter(function(item, index, arr) {
//当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
return arr.indexOf(item, 0) === index;
});
}
var arr = [1,1,'a', 'a','true','true', 'null',true,true,false,false, undefined,undefined, null,null,NaN, NaN,'NaN', {},{}];
console.log(unique(arr)) // [1, "a", "true", "null", true, false, undefined, null, "NaN", {…}, {…}]
NaN没了,{}没去重
实现数组扁平化
方法一:
var newArr = []
function flatten(arr) {
for (var i = 0; i < arr.length; i++) {
if (Object.prototype.toString.call(arr[i]) === '[object Array]') {
flatten(arr[i])
} else {
newArr.push(arr[i])
}
}
}
var arr = [1,[2,3,[4,5,[6],7]]]
flatten(arr)
console.log(newArr) // [1, 2, 3, 4, 5, 6, 7]
方法二:
var flatten = function(array) {
return array.reduce(function(previous, val) {
if (Object.prototype.toString.call(val) !== '[object Array]') {
return previous.push(val), previous
}
return Array.prototype.push.apply(previous, flatten(val)), previous
}, [])
}
var arr = [1,[2,3,[4,5,[6],7]]]
console.log(flatten(arr)) // [1, 2, 3, 4, 5, 6, 7]
方法三:
function flatten(arr) {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr)
}
return arr
}
var arr = [1,[2,3,[4,5,[6],7]]]
console.log(flatten(arr)) // [1, 2, 3, 4, 5, 6, 7]
js实现数组乱序
数组乱序的意思是,把数组内的所有元素排列顺序打乱。
方法一:
常用的办法是给数组原生的sort方法传入一个函数,此函数随机返回1或-1,达到随机排列数组元素的目的。
var arr = [1,2,3,4,5,6,7,8]
arr.sort(function(a,b){ return Math.random()>.5 ? -1 : 1;});
console.log(arr) // 顺序是随机的 这里给出我运行出的一种:[7, 4, 8, 2, 6, 3, 5, 1]
方法二: 该方法效率比方法一高,但是比较复杂
if (!Array.prototype.shuffle) {
Array.prototype.shuffle = function() {
for(var j, x, i = this.length; i; j = parseInt(Math.random() * i), x = this[--i], this[i] = this[j], this[j] = x);
return this;
};
}
var arr = [1,2,3,4,5,6,7,8]
arr.shuffle();
console.log(arr)
js实现深拷贝
方法一: 使用递归的方式实现深拷贝
//使用递归的方式实现数组、对象的深拷贝
function deepClone1(obj) {
//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
var objClone = Array.isArray(obj) ? [] : {};
//进行深拷贝的不能为空,并且是对象或者是
if (obj && typeof obj === "object") {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deepClone1(obj[key]);
} else {
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
方法二: 通过 JSON 对象实现深拷贝
//通过js的内置对象JSON来进行数组对象的深拷贝
function deepClone2(obj) {
var _obj = JSON.stringify(obj),
objClone = JSON.parse(_obj);
return objClone;
}
缺点:
- 如果
obj
里面有时间对象,则JSON.stringify
后再JSON.parse
的结果,时间将只是字符串的形式。而不是时间对象; - 如果
obj
里有RegExp
、Error
对象,则序列化的结果将只得到空对象; - 如果
obj
里有函数,undefined
,则序列化的结果会把函数或undefined
丢失; - 如果
obj
里有NaN
、Infinity
和-Infinity
,则序列化的结果会变成null
JSON.stringify()
只能序列化对象的可枚举的自有属性,例如 如果obj
中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))
深拷贝后,会丢弃对象的constructor;
- 如果对象中存在循环引用的情况也无法正确实现深拷贝;
如果拷贝的对象不涉及上面讲的情况,可以使用JSON.parse(JSON.stringify(obj))
实现深拷贝
方法三: 通过jQuery的extend
方法实现深拷贝
var array = [1,2,3,4];
var newArray = $.extend(true,[],array);
方法四: Object.assign()
拷贝
当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝。
方法五: lodash函数库实现深拷贝
别单看看,要手敲敲,实践出真知
未完待续。。。