Javascript学习记录——数组去重

 var arr = [1, 2, 3, 5, 5, '45', '45', 4, 1, '1', '2']
    for (var i = 0; i < 10000; i++) {
        arr.push(i)//这里给arr添加10000项,方便后面对各个方法性能的观看
    }

    /**
     * 方法一:借用一个结果数组,原数组中的元素与结果数组进行比较,若是不存在与原数组全等的元素,则将原数组元素存入结果数组中。
     * @param arr 传入的数组
     * @returns {Array} 返回的去重后的数组
     */
    function useArr(arr) {//封装函数
        var start = +new Date()//得到初始时间
        var resultArr = []//新建一个resultArr,用来保存非重复元素
        resultArr.push(arr[0])//在resultArr可以任意添加一个arr中的元素,保证后面能进入到内层for循环中
        for (var i = 1; i < arr.length; i++) {//遍历arr,从索引为1的元素开始
            var flag = true//这里利用假设成立法声明一个变量,假设arr中的第i项与resultArr中的每一项都不全等。
            for (var j = 0; j < resultArr.length; j++) {//遍历resultArr
                if (arr[i] === resultArr[j]) {//将arr的第i项与resultArr中的每一项进行比较
                    flag = false//如果resultArr中存在与arr第i项全等的元素,那么假设不成立,令flag为false,
                    break//既然有了重复的项,那么其他的项也就不用比了,直接结束内层for循环
                }
            }
            if (flag) {//如果假设成立,即resultArr中没有与arr第i全等的元素,那么就将arr添加到resultArr中
                resultArr.push(arr[i])
            }
        }
        var end = +new Date()//得到结束时间
        console.log(end - start)//输出时间差       结果约为 260ms
        return resultArr//返回结果数组
    }

    console.log(useArr(arr))




    /**
     * 方法二:arr中的元素与后面元素比较,如果存在与之全等的元素,则删除后面元素
     * @param arr
     * @returns {Array}
     */
    function useArr1(arr) {//封装函数
        var start = +new Date()//得到初始时间
        for (var i = 0; i < arr.length; i++) {//遍历arr
            for (var j = i + 1; j < arr.length; j++) {//遍历第i项后面的所有项
                if (arr[i] === arr[j]) {//比较第i项与其后面的所有项
                    arr.splice(j, 1)//若存在第J项与第i项全等,则删除第j项
                    j--//因为删除了一项j,j+1项会变为j项,为使得后面的比较顺利进行,这时就要进行j--
                }
            }
        }
        var end = +new Date()//得到结束时间
        console.log(end - start)//输出时间差     结果约为 193ms
        return arr;//返回去重后的原数组
    }
    console.log(useArr1(arr))


    /**
     * 方法三:使用indexOf,寻找resultArr中是否存在与arr中相等的元素,若没有则将arr的元素放入resultArr中
     * @param arr 传入的数组
     * @returns {Array} 返回的去重后的数组
     */
    function useArr2(arr) {//封装函数
        var start = +new Date()//得到初始时间
        var resultArr = []//新建一个resultArr,存放非重复元素
        for (var i = 0; i < arr.length; i++) {//遍历arr
            if (resultArr.indexOf(arr[i]) == -1) {//在resultArr中寻找是否存在与arr的第i项相等的元素,结果为-1表示不存在(indexOf寻找的是全等元素)
                resultArr.push(arr[i])//结果数组中若不存在与arr第i项相等的元素,则将arr的第i项存入resultArr中
            }
        }
        var end = +new Date()//得到结束时间
        console.log(end - start)//输出时间差     结果约为244ms
        return resultArr//返回结果数组
    }
    console.log(useArr2(arr))


    /**
     * 方法四:数组中元素与自身元素进行比较,跳过有重复项的左值,每次取没有重复项的最右值,
     * @param arr 传入的数组
     * @returns {Array} 返回的去重后的数组
     */
    function useArr3(arr) {//封装函数
        var start = +new Date()//得到初始时间
        var resultArr = []//新建一个resultArr,保存去重后的元素
        for (var i = 0; i < arr.length; i++) {//遍历arr
            for (var j = i + 1; j < arr.length; j++) {//取出第i项后面的比较项
                if (arr[i] === arr[j]) {
                    j = ++i//如果在第i项后面存在与第i项全等的元素,那么就跳过第i项,从i+1项开始,再次比较(虽然内层循环还在继续
                           //但外层相当于进入下一次的i循环),直到内层for循环走完依旧没有全等的元素
                }
            }
            resultArr.push(arr[i])//如果第i项后面与之全等的元素,那么就将arr的第i项添加到resultArr中
        }
        var end = +new Date()//得到结束时间
        console.log(end - start)//输出时间差     结果约为 214ms
        return resultArr//返回去重后的数组
    }
    console.log(useArr3(arr))

    /**
     * 方法五:使用对象,在对象中查找是否存在以数组元素为属性的属性,若是不存在,则将该元素添加到对象的属性中,
     *        因为中括号内的属性名都是以字符串形式进行查找,因此会将类似数值1与字符串'1'当做重复项,这时就要
     *        可以将数值元素的类型值作为属性值保存在对应的属性中
     * @param arr 传入的数值
     * @returns {Array} 返回的去重后的数值
     */
    function useArr4(arr) {//封装函数
        var start = +new Date()//得到初始时间
        var obj = {}, resultArr = [];//新建一个空对象,进行比较,一个空数组保存非重复元素
        for (var i = 0; i < arr.length; i++) {//遍历arr
            var type = typeof arr[i]//声明一个变量,保存数组中第i项元素值的类型
            if (!obj[arr[i]]) {//判断:如果对象中的数组元素属性不存在
                obj[arr[i]] = type//那么就将数组元素保存为对象的属性,并将数组元素值的类型保存为属性值
                resultArr.push(arr[i])//同时将满足条件的数组元素添加到resultArr中
            } else if (obj[arr[i]].indexOf(type) == -1) {//接着判断:未满足上一个if条件的所有arr的元素进入到这个else if中,以这些元素作为对象的属性查找属性值
                //如果没有与之相等(不全等)的属性的属性值,也就是数组中存在与该相等但不全的元素,那么就将该元素添加到resultArr中
                resultArr.push(arr[i])
            }
        }
        var end = +new Date()//得到结束时间
        console.log(end - start)//输出时间差     结果约为 3ms
        return resultArr//返回去重后的数组
    }
    console.log(useArr4(arr))

    //方法五的性能最佳,但是新建了一个对象,占用空间即内存大,空间换时间

 

posted @ 2016-11-15 23:45  Binnear  阅读(176)  评论(0编辑  收藏  举报