为了案例的综合性,尽量采用对象数组的方式,以及对象数组混合普通数组
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进去数组result
arr[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 = 0
for (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)