• 技术文章 >web前端 >js教程

    JavaScript专题之二:数组去重

    coldplay.xixicoldplay.xixi2021-03-03 10:23:45转载441

    目录

    (相关免费学习推荐:javascript视频教程

    在这里插入图片描述

    一、双层循环

    const unique = (arr)=>{
        for(let i = 0; i < arr.length; i++){
            for(let j = i + 1; j < arr.length; j++){
                if(arr[i] === arr[j]){
                    arr.splice(j, 1); // 移除重复元素
                    j--; // 修正下标
                }
            }
        }
        return arr;};const unique = (arr)=>{
        var arr = [1, '1', '1', 1, 2, true, false, true, 3, 2, 2, 1];
        var newArr = [];
        for(let i = 0; i < arr.length; i++){
            for(var j = 0; j < newArr.length; j++){ // 注意var声明的j
                if(arr[i] === newArr[j]) break; // 新数组已存在当前值
            }
            if(j === newArr.length){ // 此时j和newArr长度相等,没有被中断
                newArr.push(arr[i]);
            }
        }
        return newArr;}unique([1, '1', '1', 1, 2, true, false, true, 3, 2, 2, 1]); // [ 1, '1', 2, true, false, 3 ]

    核心点:

    二、indexOf和includes

    2.1 indexOf简化一层循环判断

    核心点:

    代码:

    const unique = (arr) => {
        var res = [];
        for (let i = 0; i < arr.length; i++){
            if(res.indexOf(arr[i]) === -1 ){
                res.push(arr[i]);
            }
        }
        return res;}
    2.2 includes简化一层循环判断

    核心点:

    代码:

    const unique = (arr) => {
        var res = [];
        for (let i = 0; i < arr.length; i++){
            if(!res.includes(arr[i])){
                res.push(arr[i]);
            }
        }
        return res;}
    2.3 indexOf和includes对于当前场景的选择

    在这里我们推荐使用includes来查找元素:

    返回值可以直接作为if的条件语句,简洁

    if(res.indexOf(arr[i]) !== -1 ){ todo }// orif(res.includes(arr[i])){ todo }

    识别NaN

    如果数组中有NaN,你又正好需要判断数组是否有存在NaN,这时你使用indexOf是无法判断的,你必须使用includes这个方法。

    var arr = [NaN, NaN];arr.indexOf(NaN); // -1arr.includes(NaN); // true

    识别undefined

    如果数组中有undefined值,includes会认为空的值是undefined,而indexOf不会。

    var arr = new Array(3);console.log(arr.indexOf(undefined)); //-1console.log(arr.includes(undefined)) //true

    三、排序去重

    核心点:

    代码:

    var arr = [1, 1, '1'];function unique(arr) {
        var res = [];
        var sortedArr = arr.concat().sort();
        var last;
        for (var i = 0; i < sortedArr.length ; i++) {
            // 如果是第一个元素或者相邻的元素不相同
            if (!i || last !== sortedArr[i]) {
                res.push(sortedArr[i])
            }
            last = sortedArr[i]; // 记录上一个值
        }
        return res;}console.log(unique(array));

    四、filter

    核心点:

    代码:

    var arr = [1, 2, 1, 1, '1'];const unique = function (arr) {
        var res = arr.filter(function(item, index, arr){
            return arr.indexOf(item) === index;
        })
        return res;}console.log(unique(arr)); // [ 1, 2, '1' ]

    结合排序的思路:

    var arr = [1, 2, 1, 1, '1'];const unique = function (arr) {
        return arr.concat().sort().filter(function(item, index, arr){
            return !index || item !== arr[index - 1]
        })}console.log(unique(arr));

    五、键值对(key-value)

    前面提到的几种方式总结下来大致分为

    1. 非排序数组,两次遍历判断(遍历、查询)
    2. 排序数组,相邻元素比较

    我们再提出一种方式,利用Object对象 key-value的方式,来统计数组中元素出现的个数,初步判断逻辑也有两种

    [1,1,1,2,2,3,'3']举例:

    1. 统计每个元素出现的次数,obj:{1: 3, 2: 2, 3: 3}, 返回这个objkey而不管他们的value
    2. 只元素首次出现,再次出现则证明他是重复元素
    5.1 统计次数
    var arr = [1, 2, 1, 1, '1', 3, 3];const unique = function(arr) {
        var obj = {};
        var res = [];
        arr.forEach(item => {
            if (!obj[item]) {
                obj[item] = true;
                res.push(item);
            }
        });
        return res;}console.log(unique(arr)); // [1, 2, 3]
    5.2 结合filter
    var arr = [1, 2, 1, 1, '1'];const unique = function(arr) {
        var obj = {};
        return arr.filter(function(item, index, arr){
            return obj.hasOwnProperty(item) ? false : (obj[item] = true)
        })}console.log(unique(arr)); // [1, 2]
    5.3 key: value存在的问题

    对象的属性是字符串类型的,即本身数字1字符串‘1’是不同的,但保存到对象中时会发生隐式类型转换,导致去重存在一定的隐患。

    考虑到string和number的区别(typeof 1 === ‘number’, typeof ‘1’ === ‘string’),

    所以我们可以使用 typeof item + item 拼成字符串作为 key 值来避免这个问题:

    var arr = [1, 2, 1, 1, '1', 3, 3, '2'];const unique = function(arr) {
        var obj = {};
        var res = [];
        arr.forEach(item => {
            if (!obj[typeof item + item]) {
                obj[typeof item + item] = true;
                res.push(item);
            }
        });
        return res;}console.log(unique(arr)); // [ 1, 2, '1', 3, '2' ]

    六、ES6

    随着 ES6 的到来,去重的方法又有了进展,比如我们可以使用 Set 和 Map 数据结构。

    6.1 Set

    Set:它允许你存储任何类型的唯一值,无论是原始值或者是对象引用

    代码:

    var arr = [1, 2, 1, '1', '2'];const unique = function(arr) {
       return Array.from(new Set(arr));}console.log(unique(arr)); // [ 1, 2, '1', '2' ]

    简化1:

    function unique(array) {
        return [...new Set(array)];}

    简化2:

    var unique = (a) => [...new Set(a)]
    6.2 Map

    Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。

    function unique (arr) {
        const newMap = new Map()
        return arr.filter((a) => !newMap.has(a) && newMap.set(a, 1));}

    写到这里比较常规的数组去重方法就总结的差不多了,如果需要更强大的去重方法,我们需要对他们进行组合,而且因为场景的不同,我们所实现的方法并不一定能涵盖到

    相关免费学习推荐:javascript(视频)

    以上就是JavaScript专题之二:数组去重的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:CSDN,如有侵犯,请联系admin@php.cn删除
    专题推荐:JavaScript 数组去重
    上一篇:浅谈使用nodejs实现一个简单的网页爬虫功能(实例分享) 下一篇:js怎么换行
    大前端线上培训班

    相关文章推荐

    • 浅谈javascript中数组Array的添加/删除操作• 一起看看JavaScript与CSS和Sass如何进行交互• 了解JavaScript基础(非常详细)• javascript如何换行• javascript和typescript的区别是什么

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网