数组去重算法总结

const testArray = [
{
  label: 'Banana',
  color: 'yellow',
  taste: 'sweet',
  price: 4.38,
  hometown: 'Tailand',
  id: 5
},{
  label: 'Apple',
  color: 'red',
  taste: 'crisp',
  price: 3.99,
  hometown: 'Qingdao',
  id: 4
},{
  label: 'Grape',
  color: 'purple',
  taste: 'bitter',
  price: 2.50,
  hometown: 'Dalian',
  id: 3
},{
  label: 'Peach',
  color: 'pink',
  taste: 'sour',
  price: 8.88,
  hometown: 'Beijing',
  id: 2
},{
  label: 'Banana',
  color: 'yellow',
  taste: 'sweet',
  price: 4.38,
  hometown: 'Tailand',
  id: 5
}]

const testObjArray = [
{
  label: 'Banana',
  color: 'yellow',
  taste: 'sweet',
  price: 4.38,
  hometown: 'Tailand',
  id: 5
},{
  label: 'Apple',
  color: 'red',
  taste: 'crisp',
  price: 3.99,
  hometown: 'Qingdao',
  id: 4
},{
  label: 'Grape',
  color: 'purple',
  taste: 'bitter',
  price: 2.50,
  hometown: 'Dalian',
  id: 3
},{
  label: 'Peach',
  color: 'pink',
  taste: 'sour',
  price: 8.88,
  hometown: 'Beijing',
  id: 2
},{
  label: 'Banana',
  color: 'yellow',
  taste: 'sweet',
  price: 4.38,
  hometown: 'Tailand',
  id: 5
}]

const testArrayStore = [4, 9, 2, 4, 4, 4, 9, 2, 1, 5, 1, 3, 2, 2, 4]
const testArrStore = [9, 6, 3, 9, 3]
const testArr = ['apple', 'pear', 'grape', 'apple', 'grape']

// 方法一:Set()
// 对于数组项是对象的数组,不能直接去重,数组项是字符串或者数字的可以直接去重
// 时间复杂度是O(1)
let delRepeatFunc = function (arr) {
    let newObj = new Set(arr)
    let newArray = Array.from(newObj)
    console.log('去重的结果')
    console.log(newArray)
}

// delRepeatFunc(testArray)
// delRepeatFunc(testArrayStore)
// delRepeatFunc(testArr)

// 方法二:两次遍历挨个对比有没有
// indexOf 或者 includes实际上也是一次遍历
// 判断新数组里面有没有当前遍历的元素:includes()(返回布尔值,区分大小写);indexOf()(返回数字,表示当前遍历的元素在目标数组中的位置,-1代表没有)
// 判断数组项是对象还是普通的字符:item instanceof TYPE(返回布尔值,Object是true); typeof(item) (返回数据类型名称,返回的名称是字符串类型,object,string,number等)
// 时间复杂度是O(n^2)
let delRepeatArray = function (arr) {
    let storeArr = []
    arr.forEach((item, index) => {
        let isInstance = item instanceof Object
        console.log(isInstance)
        if(isInstance) {
            // if(JSON.stringify(storeArr).indexOf(JSON.stringify(item)) == -1) {
            //     storeArr.push(item)
            // }
            if(!JSON.stringify(storeArr).includes(JSON.stringify(item))) {
                storeArr.push(item)
            }
        } else {
            // if(storeArr.indexOf(item) == -1) {
            //     storeArr.push(item)
            // }
            if(!storeArr.includes(item)) {
                storeArr.push(item)
            }
        }
        // let type = typeof(item)
        // if(type == 'object') {
        //     if(JSON.stringify(storeArr).indexOf(JSON.stringify(item)) == -1) {
        //         storeArr.push(item)
        //     }
        // } else {
        //     if(storeArr.indexOf(item) == -1) {
        //         storeArr.push(item)
        //     }
        // }
    })
    console.log('去重的结果')
    console.log(storeArr)
}


// delRepeatArray(testArray)
// delRepeatArray(testArrayStore)
// delRepeatArray(testArr)


// 方法三:filter结合indexOf
// filter循环提供了筛选功能,可达到去重的作用,但是效率不是十分高哦
// 对于数组项是对象的数组,不能直接去重
let distinct = function (a, b) {
    let arr = a.concat(b)
    return arr.filter((item, index)=> {
        return arr.indexOf(item) === index
    })
}

// let result = distinct(testObjArray, testArray)
// console.log(result.length)


// 方法四:sort()先排序,再比较相邻两个元素相等不相等
// 数组元素是对象的话,加大了排序的复杂度
// 性能比较高的一种算法 没有set性能高
let delRepeatByResort = function (array) {
    let resultArray = []
    array = array.sort()
    resultArray.push(array[0])
    array.forEach((item, index) => {
        if(index !== array.length - 1) {
            if(array[index] !== array[index + 1]) {
                resultArray.push(array[index + 1])
            }
        }
    })

    console.log('去重结果')
    console.log(resultArray)
}
// delRepeatByResort(testArrayStore)


// 方法五:对象的属性不会重复
// 效率最高哦
let distinctArray = function (arr) {
    console.log(arr)
    let result = []
    let obj = {}
    for (let i of arr) {
        if (!obj[i]) {
            result.push(i)
            obj[i] = 2
        }
    }
    console.log(result)
}

// distinctArray(testArrayStore)


// 方法六:对象的属性不会重复 用hasOwnProperty判断对象有没有指定属性
// for in:i是索引,arr[i]是数组元素值;for of:i是数组元素值,没有索引
let filterRepeat = function (arr) {
    console.log(arr)
    let obj = {}
    let resultGroup = []
    // for (let i of arr) {
    //     if(!obj.hasOwnProperty(i)) {
    //         resultGroup.push(i)
    //         obj[i] = 1
    //     }
    // }
    for (let i in arr) {
        if(!obj.hasOwnProperty(arr[i])) {
            resultGroup.push(arr[i])
            obj[arr[i]] = 1
        }
    }
    console.log(resultGroup)
}

// filterRepeat(testArrayStore)

// 方法七:map,map的结构类似于对象的结构,判断map中有没有数组中指定的键即可
let mapRepeat = function (arr) {
    console.log(arr)
    let map = new Map()
    let mapResult = new Array()
    for(let i = 0; i < arr.length; i++) {
        if(map.has(arr[i])) {
            map.set(arr[i], true)
        } else {
            map.set(arr[i], false)
            mapResult.push(arr[i])
        }
    }
    console.log('结果')
    console.log(mapResult)
}

mapRepeat(testArrayStore)


// 方法八:递归,用loop实现循环,能不用递归就别用,性能低啊
let loopRepeat = function (array) {
    let len = array.length
    let arr = array.sort()
    console.log(arr)

    function loop (index) {
        if(index >= 1) {
            if(arr[index] === arr[index - 1]) {
                arr.splice(index, 1)
            }
            loop(index - 1)
        }
    }
    loop(len - 1)

    console.log('结果')
    console.log(arr)
}

loopRepeat(testArrayStore)
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章