Javascript 二维数组去重

[[a,1],[b,2],[a,2]] 去除[a,2]

输入一串url 和一个待去除参数,输出筛选后的结果,第二个参数缺省的话,去除重复部分。

stripUrlParams('www.codewars.com?a=1&b=2&a=2', ['b']) 
// returns 'www.codewars.com?a=1'

思路是先将querry参数变成二维数组再去重,对象的键值是唯一的,将参数转化为数组后,遍历数组,若在对象中已经存在参数名称则跳过;否则添加参数与值;然后遍历对象组合URL。代码如下:

function stripUrlParams(url, arr) {
    var domain = url.substr(0, url.lastIndexOf('?')+1);
    if(url.lastIndexOf('?') == -1) 
        domian = url;
    var query = url.substr(url.lastIndexOf('?')+1);
    var obj = {};
    var argsArr = query.split('&');
    for(var i in argsArr) {
        var tmp = argsArr[i].split('=');
        if(obj[tmp[0]] == null)
            obj[tmp[0]]=tmp[1];
    }
    query = "";
    for(var i in obj) {
        // 去掉arr中的参数
        var is = true;
        if(arr != null)
            for(var j in arr) {
                if(i == j) 
                    is = false;
            }
        if(is) {
            query += i + "=" + obj[i]+"&";
        }
    }
    return domain + query.substr(0, query.length-1);
}

var url = stripUrlParams('www.codewars.com?a=1&b=2&a=2', ['b'])
console.log(url);

仅仅对于去重问题,可以简单的用一个reduce解决:

var arr = [['a', 1], ['b', 2], ['a', 2]];

var result = arr.reduce((function () {
  var map = {};
  return function (result, next) {
    var key = next[0];
    if (!map[key]) {
      map[key] = true;
      result.push(next);
    }
    return result;
  };
})(), []);

console.log(JSON.stringify(result));

第二种方法:

function stripUrlParams(url, varible) {
    var urlArr = url.split('?')[1].split('&').map(function(item) {
        return item.split('=');
    })
    var hash = {};
    var result = [];
    for (var i = 0; i < urlArr.length; i++) {
        hash[urlArr[i][0]] ? '' : (hash[urlArr[i][0]] = true, urlArr[i][0] !== varible && result.push(urlArr[i]));

    }
    return url.split('?')[0] + '?' + result.reduce(function(prev, next) {
        return prev + next.join('=');
    }, '')
}
console.log(stripUrlParams('www.codewars.com?a=1&b=2&a=2&d=8', 'b'));
//www.codewars.com?a=1d=8

第三种:
思路:
将二维数组转换成一位数组去比较,将二级元素转换为字符串比较方便,但是为了区分类型,引入typeof拼接,之后对这个一维数组查重

function fun(input) {
    var input = input || [];
    var temp = input.map(function (item) {
        return item.map(function (_item) {
            return _item + ' ' + typeof _item;
        }).join('|');
    });

    // temp : ['a string|1 number', 'b string|2 number', 'a string|2 number']

    var indexArr = [];
    temp.map(function (item, index, arr) {
        for (var i = 0; i < index; i++) {
            if (arr[i] !== item) indexArr.push(index);
        }
    });

    var result = [];
    for (var i = 0; i < indexArr.length; i++) {
        result.push(input[i]);
    }

    return result;
}

console.log(fun(input));

单层循环来搞定。这个特殊问题,可以转化到单层数组去重问题上。

var tidy = function(arr) {
    var i = 0,
        j = arr.length,
        cache = {},
        key, result = [];
    for (; i < j; i++) {
        key = arr[i][0];
        key = typeof(key) + key;
        if (!cache[key]) {
            cache[key] = 1;
            result.push(arr[i]);
        }
    }
    return result;
};

测试

var arr = [['a', 1], ['b', 2], ['a', 2]];
tidy(arr);
var url = 'www.codewars.com?a=1&b=2&a=2';

    var usArr = url.split('?')[1];
    var usMap = {};
    usArr.split('&').forEach(function(a,b){
        var s = a.split('=');
        !usMap[s[0]] && (usMap[s[0]] = s[1]);
    })
    console.log(usMap)
<think>嗯,用户想了解如何用JavaScript二维数组进行。首先,我得回忆一下常见的数组方法,比如用Set或者遍历比较。不过二维数组的话,里面的元素是数组,而Set在处理对象引用时,无法直接判断是否复,因为不同的数组实例即使内容相同,也被视为不同的。所以直接转成字符串可能是个办法,比如把每个子数组用JSON.stringify转成字符串,然后存到Set里,最后再转换回来。 不过,这样可能会有问题吗?比如,子数组里的元素顺序不同,比如[1,2]和[2,1]会被视为不同的字符串,但用户可能希望它们算复。这时候是否需要先对子数组排序后再处理?用户的需求可能有两种情况:一种是严格保持子数组顺序相同才算复,另一种是元素相同但顺序不同也算复。这时候可能需要分情况讨论,或者给出不同的解决方案。 另外,效率也是一个考虑点。如果数组很大,转换成字符串可能会影响性能。这时候有没有更好的方法?比如遍历数组,逐个比较子数组的内容是否相同。不过这样的时间复杂度会比较高,是O(n²),对于大数据量可能不合适。所以需要根据使用场景来选择合适的方案。 然后,我应该给出具体的代码示例。比如,使用Set和JSON的方法,或者结合排序的方法。同时,还要注意处理特殊情况,比如子数组中包含对象或者其他非基本类型的数据,这时候JSON.stringify可能会有问题,比如对象属性顺序不同导致字符串不同。不过用户的问题是关于二维数组,可能里面的元素都是基本类型,比如数字或者字符串,所以暂时可以忽略这种情况。 另外,还要考虑代码的兼容性。Set在ES6之后支持,所以如果需要支持旧浏览器可能需要转译。不过大多数现代环境应该没问题。 总结步骤的话,应该是: 1. 遍历原数组的每个子数组。 2. 将子数组转换为字符串,比如用JSON.stringify。 3. 利用Set这些字符串。 4. 将后的字符串转换回数组。 或者,如果考虑元素顺序无关,先排序子数组再转换字符串。 最后,给出这两种情况的代码示例,并说明它们的区别和适用场景。</think>在JavaScript中对二维数组,需根据子数组内容进行判断。以下是分步解决方案: 一、基础方法(顺序敏感) ```javascript function unique2DArray(arr) { const seen = new Set(); return arr.filter(subArr => { const key = JSON.stringify(subArr); return seen.has(key) ? false : seen.add(key); }); } // 示例 const arr = [[1,2], [3,4], [1,2], [5,6]]; console.log(unique2DArray(arr)); // 输出 [[1,2], [3,4], [5,6]] ``` 原理说明: 1. 使用`Set`存储序列化后的子数组字符串 2. 通过`JSON.stringify`将子数组转为唯一标识 3. 利用`filter`实现过滤 二、顺序不敏感版本(元素相同即视为复) ```javascript function unique2DArrayUnordered(arr) { const seen = new Set(); return arr.filter(subArr => { const sorted = [...subArr].sort(); const key = JSON.stringify(sorted); return seen.has(key) ? false : seen.add(key); }); } // 示例 const arr = [[2,1], [1,2], [3,4], [4,3]]; console.log(unique2DArrayUnordered(arr)); // 输出 [[2,1], [3,4]] ``` 三、性能优化建议 1. 大数据量时优先使用`new Set()`而不是数组遍历 2. 如果子数组元素都是原始类型,可用`join()`代替`JSON.stringify` ```javascript const key = subArr.join('|'); // 适用于数字/字符串且不含分隔符 ``` 四、特殊处理场景 1. 包含对象的二维数组: ```javascript // 需要自定义序列化方法 const key = subArr.map(item => JSON.stringify(item)).join('#'); ``` 五、注意事项 1. `JSON.stringify`对`undefined`和函数类型处理不一致 2. 浮点数精度问题(如1.0会被转为1) 3. 大数组建议使用Map替代Set提升性能 根据实际需求选择合适的方法,常规情况下基础方法即可满足大多数需求。如果数组元素顺序不影响等价判断,推荐使用排序后的优化版本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值