为了案例的综合性,尽量采用对象数组的方式,以及对象数组混合普通数组
1数组去重
// 数组去重,去重指的是重复的只留下一个,而不是全删了
// 这里以数组对象与普通对象为例子
// 并且是以单个数组去重为例子
// 多个数组去重没有必要赘述
// 因为多个数组去重,也不过是数组concat之后,再去重罢了// 1.new set方式
let arr1 = [{ a: 1, b: 2 }, { a: 1, b: 1 }, { a: 1, b: 2 }]
let arr3 = [{ a: 1, b: 2 }, { a: 1, b: 1 }, { a: 1, b: 2 }, 'jhjlhjk', 'jhjlhjk', 'sdfdf']
let arr2 = [1, 2, 1]
// console.log([...new Set([...arr2])])
// console.log([...new Set([...arr1])]) //无法去重引用对象类型// 2.filter方式
// indexof
function filterUnique1(arr) {return arr.filter((el, index, self) => {return self.indexOf(el, 0) === index//第一个参数:要检索的元素,第二个参数是开始索引的位置})
}
// findindex
function filterUnique2(arr) {return arr.filter((el, index, self) => {return self.findIndex(item => item.b == el.b) === index //找到相同的元素的索引看,是否与这个相同,// 同样是一样解释,不过这个函数可以写入回调,可操作性更大一些})
}
// 都是一样的解释,由于这里不是正则,不会/g全局匹配,所以只会索引到第一元素
// 于是当出现第二个重复的元素,indexof返回的依然只是第一个重复元素的index
// 而这显然和当前第二个重复元素的index不会相同,就不会返回,就去掉重复元素了// console.log(filterUnique1(arr1))// 用indexof同样无法去重引用对象类型
// console.log(filterUnique2(arr1))// 可以去重引用对象类型// 3.普通的双重for循环
// 法1
function forUnique1(arr) {let newArr = []for (let i = 0; i < arr.length; i++) {for (let j = 0; j < arr.length; j++) {if (arr[i].b != arr[j].b) {// 如果不相同,并且newArr中没有就push进去let flag = newArr.some(el => el.b == arr[j].b)!flag ? newArr.push(arr[j]) : ''}}}return newArr
}// console.log(forUnique1(arr1)) //可以去重引用对象类型// 法2
function forUnique2(arr) {arr = arr.concat();for (let i = 0, len = arr.length; i < len; i++) {for (let j = i + 1; j < len; j++) {if (arr[i].b === arr[j].b) {arr.splice(j, 1);// splice可以改变数组长度,所以数组长度len和j的下标减一len--;j--;}}}return arr;
}
// console.log(forUnique2(arr1)) //可以去重引用对象类型// 4.用sort sort排序对象数组,排序之后就可以放心的比较相邻的,不用担心后面隔着又出现重复的,不同于上一个的就push进数组
function sortUnique(arr) {arr = arr.concat().sort((prev, next) => prev.b - next.b) //sort排序对象数组,然后...let result = [];arr[0] && arr[0] != 0 ? result.push(arr[0]) : ''// result中保存排序后的数组的第一项for (let i = 1, len = arr.length; i < len; i++) {// 如果相邻两项元素不等,则push进去数组resultarr[i].b !== arr[i - 1].b && result.push(arr[i]);}return result;
}
// console.log(sortUnique(arr1)) //可以去重引用对象类型// 5.for of object
function forOfUnique(arr) {arr = arr.concat();let result = [];let obj = {};for (const i of arr) {// console.log(i, arr[i], obj) //原来for of循环 i是每一项....// 数组的键是单独的// 把arr的值作为obj的键,如果不存在才push进去,存在就不再push进去// 不过如果是对象数组,那么不要把对象作为键,而是身上用来标识比较去重的那个属性// 我此处是b属性,一般也只会需要一个属性,比如判断id不同的// 如果确实有多个属性,那么这种方法就不适合了,因为键只能有一个// 那么就用上面的方法呗,能够在if里写多个判断的那种if (!obj[i.b]) {result.push(i);obj[i.b] = 1 //把arr的值作为obj的键,随便赋个值,无影响}}return result;
}
// console.log(forOfUnique(arr1)) //可以去重引用对象类型
// console.log(forOfUnique(arr2))// 6.reduce
function reduceUnique(arr) {arr = arr.concat();let result = [];let obj = {}result = arr.reduce((prev, curv) => {if (!obj[curv.b]) {prev.push(curv)obj[curv.b] = 1 //把arr的值作为obj的键,随便赋个值,无影响}return prev}, [])return result
}
console.log(reduceUnique(arr1)) //可以去重引用对象类型
// console.log(reduceUnique(arr2))// includes 也无法判断引用对象类型(arr1这种),基本就是判断一下普通数组(arr2这种)//indexOf 第一个参数:要检索的元素,第二个参数是开始索引的位置,也无法判断引用对象类型(arr1这种),基本就是判断一下普通数组(arr2这种)// findIndex 可以判断查找引用对象类型,为何呢,因为不同于indexof,他可以传回调,可操作空间更大,自然可以判断对象的属性// reduce 后面加个[]和不加[]的区别
// 基本情况: reduce是个迭代器,prev表示的是上一次遍历的return的结果,curv表示当前遍历的这一项的值
// 如果没加[],那么第一次遍历的时候,prev表示第一项,curv表示第二项,之后是基本情况
// 如果加了[],那么第一次遍历的时候,prev表示这个数组,curv表示第一项,之后是基本情况,注意我此处只放个空数组,实际情况你可以放已经有值的数组等等// arr = arr.concat().sort((prev, next) => prev.b - next.b) //sort排序对象数组,// some 有时候里面也写some或者every啥的来判断是否存在//补充一点,上述数组操作不乏很多for循环判断数组中是否存在这个元素或者是不存在,不过与其用for循环//不如用map与some,every什么的,语法更加简洁
未完待续
下次再更
2.两个数组取出相同部分,得到一个新数组 以及两个数组取出不同部分,得到一个新数组
暂时先写这几个
let arr1 = [{ a: 1, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 3 }]
let arr2 = [{ a: 1, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 4 }, { a: 1, b: 5 },]
// 一.两个数组取出相同部分,得到一个新数组
// 1.双重for循环/**
* 获取两个数组的公共部分
*/
function getSameArr(arr1, arr2) {let result = []let j = 0for (let i = 0; i < arr1.length; i++) {for (let k = 0; k < arr2.length; k++) {if (arr1[i].a === arr2[k].a && arr1[i].b === arr2[k].b) {result[j] = arr1[i]++j}}}return result
}
console.log(getSameArr(arr1, arr2))// 2.如果是普通数组而不是对象数组,那就很简单了,方法很多,这里随便举个案例
let result1 = []
let list1 = [1, 2, 3, 4, 5]
let val1 = [1, 2, 3]
result1 = list1.filter(number => val1.includes(number))
console.log(result1)// 二.两个数组取出不同部分,得到一个新数组
// 1.双重for循环
/**
* 获取两个数组之间的不同的部分
*/
function getdifferentArr(arr1, arr2) {let result = []let tmp = arr1.concat(arr2)let o = {}for (let i = 0; i < tmp.length; i++) {if (tmp[i].b in o) {o[tmp[i].b].num++} else {o[tmp[i].b] = { num: 1, item: tmp[i] }}}for (let x in o) if (o[x].num === 1) result.push(o[x].item)return result
}
console.log(getdifferentArr(arr1, arr2))// 2.如果是普通数组而不是对象数组,那就很简单了,方法很多,这里随便举两个案例
let result2 = []
let list2 = [1, 2, 3, 4, 5]
let val2 = [1, 2, 3]
result2 = list2.filter(number => !val2.includes(number))
console.log(result2)var arr3 = [0, 1, 2, 3, 4, 5];
var arr4 = [0, 4, 6, 1, 3, 9];
function getArrDifference(arr3, arr4) {return arr3.concat(arr4).filter(function (v, i, arr) {return arr.indexOf(v) === arr.lastIndexOf(v);});
}
console.log(getArrDifference(arr3, arr4));// in运算符 如果指定的属性在指定的对象或其原型链中,则in 运算符返回true。//补充一点,上述数组操作不乏很多for循环判断数组中是否存在这个元素或者是不存在,不过与其用for循环//不如用map与some,every什么的,语法更加简洁
3.数组a,b,a的元素要在b中存在,不在a中存在的话,就放入新数组,最后得到一个新数组
那不就是b有a没有,b中的元素,那不就是把b中与a一样的元素剔除就行了
那把a看做一个枚举类型把?只要b中的元素在这个枚举之内就不push到新数组,否则就push到新数组
这个其实很简单,还是for循环判断罢了..............
// arr1有但arr2没有,也就是最后得到的新数组是 [ { a: 1, b: 3 }]
// 或者arr2有但arr1没有,也就是最后得到的新数组是 [ { a: 1, b: 4 }, { a: 1, b: 5 }]
let arr1 = [{ a: 1, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 3 }]
let arr2 = [{ a: 1, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 4 }, { a: 1, b: 5 }]let newArr = []
arr1.map(el => {let someFlag = arr2.some(item => item.a == el.a && item.b == el.b)// 判断arr2中是否有当前这个el项// 如果有,那么则不push到新数组someFlag ? '' : newArr.push(el)
})
console.log(newArr)newArr = []
arr2.map(el => {let someFlag = arr1.some(item => item.a == el.a && item.b == el.b)// 判断arr2中是否有当前这个el项// 如果有,那么则不push到新数组someFlag ? '' : newArr.push(el)
})
console.log(newArr)// 补充一点,上述数组操作不乏很多for循环判断数组中是否存在这个元素或者是不存在,不过与其用for循环// 不如用map与some,every什么的,语法更加简洁
4.一个数组按照另一个数组顺序排序
arr1 [2,1,3]
arr2 [1,2,3,4,5]
arr1.sort((prev,next)=>{
return arr2.indexOf(prev)-arr2.indexOf(next)
})
这是arr1按照arr2排序
以及一些问题
发现一个小问题,之前用的sort排序两个数组,一个按照另一个排序,一直是少的那个以多的那个来排序,也确实应该这样,因为一般多的那个都是要排成的顺序,
但是一旦是多的那个要以少的那个排序就会有个问题,排是排了,但是没有移动位置,比如3 5 7 1 2以 2 1排序 排完后会是3 5 7 2 1而不是2 1 3 5 7
补充一点,上述数组操作不乏很多for循环判断数组中是否存在这个元素或者是不存在,不过与其用for循环
不如用map与some,every什么的,语法更加简洁
5.如果判断一个数组a是否属于数组b
// 判断a,b数组是否属于c数组
let a = [1, 2, 2, 3, 3, 4]
let b = [1, 2, 2, 3, 3, 10]
let c = [1, 2, 2, 3, 3, 4, 5, 6, 7, 8]// 思路是,循环,在c中找到一个,就把a,b数组中的数据删掉,最后循环完后看看他们的长度是否为0
let aCopy = a.concat()
let bCopy = b.concat()c.map(el => {let aIndex = aCopy.indexOf(el)if (aIndex >= 0) {aCopy.splice(aIndex, 1)}let bIndex = bCopy.indexOf(el)if (bIndex >= 0) {bCopy.splice(bIndex, 1)}
})
console.log(aCopy.length, bCopy.length)