为了账号安全,请及时绑定邮箱和手机立即绑定

从数组arr中去掉repeatArr,我能想到的最好的方法是递归,有没有比较简洁的方法?

从数组arr中去掉repeatArr,我能想到的最好的方法是递归,有没有比较简洁的方法?

尚方宝剑之说 2019-02-26 21:13:33
arr和repeatArr都不会出现重复项,而且repeatArr一定是类似数学里的集合,repeatArr是属于arr的`var arr = [1, 2, 3, 4, 5];var repeatArr = [1, 3];function distinct() {    for (var i = 0; i < arr.length; i++) {        for (var j = 0; j < repeatArr.length; j++) {            if (arr[i] == repeatArr[j]) {                arr.splice(i, 1);                distinct()                return false;            }        }    }}distinct();console.log(arr)
查看完整描述

2 回答

?
www说

TA贡献1775条经验 获得超8个赞

  1. 先把“去重”的概念说清楚吧。

  2. 去重这种,O(n) 的时间复杂度就够了。


查看完整回答
反对 回复 2019-03-01
?
紫衣仙女

TA贡献1839条经验 获得超15个赞

先说一下原来的代码。

做一个双循环也并不需要用到递归,找到重复项原地踏步就行!

直接操作外部变量也不是一个好的选择!


if (arr[i] == repeatArr[j]) {

    arr.splice(i, 1);

    i--

    break;

}

另外,

去重最常用的像上面说的,使用哈希,就不累赘了哈!


其实你可以从几个方面考虑一下上面几种答案。

1、是否纯函数或者说是否直接修改外部变量

2、性能、复杂度

3、代码可读性(这个不说了,大家都有自己的见解)


    arr.filter(item => !repeatArr.includes(item))

    

    function fp(origin, repeat) {

      return origin.filter(item => !repeat.includes(item))

    }

第一种偏函数式,不影响外部,可以很轻松封装成函数,也方便复用!

复杂度也是O(n^2),上用大白话说,其实也就是双循环。


    var arr = [1, 2, 3, 4, 5];

    var repeatArr = [1, 3];

    var map = {};

    $.map(repeatArr, function(v){map[v] = true})

    arr = $.map(arr, function(v){if(!map[v]){return v}})

    

    function hashMapUnique(origin, repeat) {

      let map = {};

      repeat.map(item => map[item] = true)

      return origin.filter(item => !map[item])

    }

第二种用也比较容易封装成函数

哈希在数据访问的时候比遍历要快,在处理的量大的情况下,性能优于第一种方法


刚刚还看到了第三种使用正则的。

还挺复杂的,最后数据类型也发生变化了。

没有尝试哈!


最后说一下你改以后的方法哈


for (var i = 0; i < repeatArr.length;i++) {

    var index = arr.indexOf(repeatArr[i]);

    arr.splice(index, 1);

}

就像yszou说的你的复杂度上没有优势!

而且使用了splice方法,直接修改了原始数组不说,且这个方法本身就比较消耗性能的。

用大白话说,splice在删除那一项以后,得把该项以后的每一项都前移一位!

可读性上面我就不评论了哈·~~~


查看完整回答
反对 回复 2019-03-01
  • 2 回答
  • 0 关注
  • 777 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信