js数组方法——找出两数组中不相同的元素的集合

JavaScript054

js数组方法——找出两数组中不相同的元素的集合,第1张

平时需求中经常遇到,找出两数组中不相同的部分。有时候会要找出被删除的元素。

indexOf是找出数组中元素第一次出现的位置。

lastIndexOf是找出数组中元素最后出现的位置。

假如两个数组合并后,重复的元素出现两次,indexOf和lastIndexOf的值是不一样的,反之,如果元素不是重复元素,那么,indexof和lastIndexOf值是一样的。

reduce()方法为归并类方法,最常见的应用场景就是,计算数组中每一项的总和。

reduce()方法会遍历数组的每一项,它接收两个参数:

第一个参数是:每次遍历都会调用的函数,而这个函数又接收四个参数,分别为:前一个值、当前项、项目的索引和数组对象,

而这个函数的返回值,会传给下一次遍历时,执行的这个方法的第一个参数。

第二个参数是:归并基础的初始值。

总结:

1.当reduce()方法的第二个值为空时,第一次循环方法中的第一个参数(prev)为数组的第一项值,第二个参数(cur)为数组的第二项值,反之,第一次循环方法中的第一个参数(prev)为reduce的第二个参数值,第二个参数(cur)为数组的第一项值。

2.reduce方法的第一个参数,就是每次遍历都会执行的匿名函数,当前函数的返回值会传给下一次执行函数的第一个值。也就是prev

reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组。

先看第一个例子:

这里可以看出,上面的例子index是从1开始的,第一次的prev的值是数组的第一个值。数组长度是4,但是reduce函数循环3次。

再看第二个例子:

这个例子index是从0开始的,第一次的prev的值是我们设置的初始值0,数组长度是4,reduce函数循环4次。

结论: 如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供initialValue,从索引0开始。

注意:如果这个数组为空,运用reduce是什么情况?

但是要是我们设置了初始值就不会报错,如下:

所以一般来说我们提供初始值通常更安全

当然最简单的就是我们常用的数组求和,求乘积了。

(1)计算数组中每个元素出现的次数

(2)数组去重

(3)将二维数组转化为一维

(3)将多维数组转化为一维

(4)、对象里的属性求和

// 原数组

    const serveralArr = [

        [1,2,4,5,23,3,2,2,4,3,5,5],

        [3,2,3,2,2,4,3,1,4,5,6],

        [3,2,4,3,2,4,1,2,5],

        [3,2,4,5,5,4,3,1,2,2],

        [3,2,23,3,4,1,3,4,5,5,4,3,1,2,2],

        [3,2,4,1,2,5,5,4,3,1,2,2],

        [3,2,4,25,5,4,3,1,2,2],

    ]

    // ES5 方法实现数学意义上的交集结果

    const intersectNoRepeatFirst = serveralArr =>{

        let minArr = serveralArr[0]

        serveralArr.forEach(item =>{

            if(item.length <minArr.length){

                minArr = item

            }

        })

        const result = []

        minArr.forEach(item =>{

            serveralArr.forEach(j =>{

                if(j.includes(item) &&!result.includes(item)){

                    result.push(item)

                }

            })

        })

        return result

    }

    // ES6 方法实现数学意义上的交集结果

    const intersectNoRepeatTwice = arrs =>{

        return arrs.reduce(function(prev,cur){

            // return [...new Set(cur.filter((item)=>prev.includes(item)))]

            return Array.from(new Set(cur.filter((item)=>prev.includes(item))))

        })

    }

    // 输出数学意义上的交集结果

    console.log(intersectNoRepeatFirst(serveralArr), intersectNoRepeatTwice(serveralArr)) // =>(5) [3, 2, 4, 1, 5](5) [3, 2, 4, 5, 1]

    // ES5 方法实现有重复元素的交集结果

    const intersectRepeat = arr =>{

        const result = []

        const tempArr = []

        arr.forEach(item =>{

            const obj = {}

            item.forEach(j =>{

                if(obj.hasOwnProperty(j)){

                    obj[j] += 1

                }else{

                    obj[j] = 1

                }

            })

            tempArr.push(obj)

        })

        let arrr = tempArr[0]

        tempArr.forEach(item =>{

            if(item.length <arrr.length){

                arrr = item

            }

        })

        const newOjb = {}

        Object.keys(arrr).forEach(item =>{

            newOjb[item] = Math.min.apply(Math, tempArr.map(function(o) {return o[item]}))

        })

        Object.keys(newOjb).forEach(item =>{

            if(newOjb[item]){

                for(let i = 0i <newOjb[item]i++){

                    result.push(Number(item))

                }

            }

        })

        return result

    }

    // 输出有重复元素的交集结果

    console.log(intersectRepeat(serveralArr)) // =>(9) [1, 2, 2, 2, 3, 3, 4, 4, 5]