数组的处理方法,感觉需要总结一下了,最近用到的特别多,各种数组之间的处理--持续更新吧

el/2023/6/3 17:02:20

为了案例的综合性,尽量采用对象数组的方式,以及对象数组混合普通数组

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)

 

http://www.ngui.cc/el/3419215.html

相关文章

一些点的记录2---持续更新

1.vue中scss的安装 cnpm i node-sass4.14.1 -D cnpm i sass-loader7.3.1 -D 在webpack.base.conf.js中的module的rules 加上 { test: /\.scss$/, loader: sass-loader!style-loader!css-loader, }, 2.如果echarts运行的时候由于v-if的切换造成重新渲染, <div v-if&quo…

computed能作为组件传值传递吗

点击后 可以 你想想,你父组件有个computed被一些数据影响着值,然后你computed传给了子组件 那子组件是不是也动态变了,是不是很爽 还有vuex的getters其实就是计算属性 看看这篇博客 https://www.jb51.net/article/159727.htm 使用场景,打个比方 若是对数据进行处理输出&a…

如何在element的相应的行上加其他dom元素实现样式与功能呢

首先这个我看element官网还真没发现咋整,没法在table里再塞一行div啥的 不过自己想了个方法,其实动态定个位就好了,其实动态定位,动态大小啥的,在之前那家公司写uniapp的时候还真是写过好多次....各种兼容,动态获取宽高啥啥的,动态设置宽高等等属性 所以这个功能我就也想到了…

关于createElement的一些点

1.这里我用h代指createElement h(div, {domProps: {innerHTML: bag}}, [h(span, {domProps: {innerHTML: bag}}, []),h(span, {domProps: {innerHTML: bag}}, []),h(img, {domProps: {innerHTML: bag},attrs: {src: https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u…

关于watch

1.今天做个需求&#xff0c;一个对象传了好几层到子组件&#xff0c;然后子组件改了&#xff0c;这个对象也要同步到变化&#xff0c;最后通过保存回调&#xff0c;得到改了的数据传回来 我直接修改传的对象&#xff0c;比如通过两个el-radio的选中切换&#xff0c;但是传的数…

关于多层组件连续传值的改值问题,子改,孙改,或者父改,对传的数据的影响

下面是结论 <!-- 1.父组件传给子组件对象,子组件改传的对象的属性,父组件中传的这个值会变吗 会变 --> <!-- 2.父组件传给子组件对象,父组件改传的对象的属性,传给了子组件这个值会变吗 会变 --> <!-- 3.爷组件传给孙组件对象,孙组件改传的对象的属性,爷组件中传…

关于防抖与节流

他们都是不停地触发 只是他们的应对不一样 防抖是每次都清除定时器再开新的定时器&#xff0c;所以就会不管你多少次点击&#xff0c;也只会有一个定时器&#xff0c; 节流就是&#xff0c;首先默认flag为true 然后执行的时候先判断flag是否true 否则return 是的话进入执行&…

关于vue中的数据传递的响应以及watch的理解

首先看看这篇说的https://www.cnblogs.com/1032473245jing/p/11102919.html 1.将父组件数据赋值给子组件数据&#xff0c;子组件间接使用&#xff0c;数据仅在mounted中渲染&#xff0c;父组件数据改变子组件数据不改变&#xff0c;需要用watch监听&#xff0c;可以深度监听 …

react中解决下拉时,多个tooltip包裹的列表中,hover时,tooltip快速触发,闪烁问题

闪烁问题&#xff0c;是由于没有用div包裹元素 下拉时不让hover到的元素触发&#xff0c;停止下拉时才触发tooltip显示 这里就涉及到如何判断滚动中和滚动结束 只需要在滚动时记录下top1&#xff0c;而滚动时节流1000调用另一函数&#xff0c;此函数中再获取当前滚动条值记录…

一篇总结型文章,this,react中的this,document等node节点原型,实例和原型上的方法属性区分等

关于严格模式 use strictconsole.log(document)//此处说明开启了严格模式,也能通过window点出其属性// 只是window被隐藏了,但凡要打印window的地方,都会打印undefinedfunction hj() {console.log(this)//严格模式下,打印undefined,非严格模式,打印window}hj()console.log(win…