【问题标题】:Remove all of the duplicate numbers in an array of numbers [duplicate]删除数字数组中的所有重复数字[重复]
【发布时间】:2019-08-10 19:43:54
【问题描述】:

我收到这个问题是为了练习,但措辞让我很困惑,因为我看到了它可能想要的 2 个结果。

无论哪种方式,我都希望看到这两种解决方案。

例如,如果我有一个数组:

let arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];

我认为这是想要最终结果:

let finalResult = [1, 2, 3, 4, 5, 8, 9, 10];

或者:

let finalResult = [1, 9, 10];

两者之间的区别,一个只是删除所有重复的数字并留下其余部分,第二个只是想要任何不重复的数字。

无论哪种方式,我都想编写两个函数,每个函数都执行一个。

这个,别人给出的,给出了我的第二个解决方案。

let elems = {},

arr2 = arr.filter(function (e) {
   if (elems[e] === undefined) {
       elems[e] = true;
    return true;
  }
  return false;
});
console.log(arr2);

我不确定第一个函数的功能(删除所有重复项)。

【问题讨论】:

  • 如果你使用的是lodash,你可以使用_.uniq()
  • 进一步,这是要求 Get all non-unique values (i.e.: duplicate/more than one occurrence) in an array 的倒数。最后,这篇文章提出了两个不同的问题,并且两者在其他地方已经有了很好的答案。
  • 在评论回答中回答“它是哪一个”的问题:如果您被要求删除重复项,我相信您应该了解第一个变体。第二个变体删除所有 具有 重复项的元素,即“原始”值及其重复项。

标签: javascript arrays duplicates


【解决方案1】:

使用SetArray.from()

let arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];

console.log(Array.from(new Set(arr)));

使用正则表达式替换

正则表达式解释here

let arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];

let res = arr
  .join(',')
  .replace(/(\b,\w+\b)(?=.*\1)/ig, '')
  .split(',')
  .map(Number);

console.log(res);

交替使用对象

let arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];

let obj = arr.reduce((acc, val) => Object.assign(acc, {
  [val]: val
}), {});

console.log(Object.values(obj));

【讨论】:

    【解决方案2】:

    只需使用简单的array.filter 单线:

    let arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];
    let finalResult = arr.filter((e, i, a) => a.indexOf(e) == i).sort(function(a, b){return a - b});
    console.log(finalResult);

    如果您想要第二个结果,可以使用另一个 filter 语句:

    let arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];
    let finalResult = arr.filter((e, i, a) => a.filter(f => f == e).length == 1).sort(function(a, b){return a - b});
    console.log(finalResult);

    【讨论】:

    • 您还可以添加.sort() 以按数字顺序对它们进行排序:.sort(function(a, b){return a - b}) on finalresult
    • 是的@Mukyuu,那也很有用
    • 值得指出的是,这种方法的运行时间将是输入大小的二次方,除非已知输入数组总是相当小,否则这可能不是很好。
    • 使用多个 array#filter、array#sort 和 array#indexOf 投票最多...这不是高性能
    • 请注意.sort() 不是必要的 - 没有排序的最终结果仍然是一个没有任何重复项的数组,只是与原始数组的顺序相同. (它确实使它与问题中的 finalResult 变量完全匹配。)
    【解决方案3】:

    对于第一部分,您可以使用Set() 和传播语法来删除重复项。

    let arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];
    let res = [...new Set(arr)]
    console.log(res)

    第二部分可以使用reduce()

    let arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];
    //to get the object with count of each number in array.
    let obj = arr.reduce((ac,a) => {
      //check if number doesnot occur before then set its count to 1
      if(!ac[a]) ac[a] = 1;
      //if number is already in object increase its count
      else ac[a]++;
      return ac;
    },{})
    //Using reduce on all the keys of object means all numbers.
    let res = Object.keys(obj).reduce((ac,a) => {
      //check if count of current number 'a' is `1` in the above object then add it into array
      if(obj[a] === 1) ac.push(+a)
      return ac;
    },[])
    console.log(res)

    【讨论】:

    • 很高兴,第二个看起来很疯狂。我假设与其他结果相比,时间复杂度会不太理想?
    • @mph85 是的,它有点复杂,因为它不会一次又一次地遍历数组,而只是存储所有结果 obj 然后过滤它。它的性能更好
    • 你能提醒我为什么我们需要spread operator吗?如果我们没有它会发生什么? @Maheer 阿里
    • 是不是因为如果我们没有它,它只会记录一个对象?
    • @mph85 不,如果我们没有它。我们将有一个Set() 内部数组。我们使用它将Set() 转换为Array
    【解决方案4】:

    您可以使用closureMap

    let arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];
    
    const build = ar => {
      const mapObj = ar.reduce((acc, e) => {
        acc.has(e) ? acc.set(e, true) : acc.set(e, false)
        return acc
      }, new Map())
      
      return function(hasDup = true) {
        if(hasDup) return [...mapObj.keys()]
        else return [...mapObj].filter(([key, val]) => !val).map(([k, v])=> k)
      }
    }
    
    const getArr = build(arr)
    
    console.log(getArr())
    console.log(getArr(false))

    【讨论】:

      【解决方案5】:

      您可以在 One Go 中创建两个数组

      let arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];
      let unique = new Set();
      let repeated = Array.from(arr.reduce((acc, curr) => {
      	acc.has(curr) ? unique.delete(curr) : acc.add(curr) && unique.add(curr);
      	return acc;
      }, new Set()));
      
      console.log(Array.from(unique))
      console.log(repeated)

      【讨论】:

      • 好朋友+1
      • 我想知道三元加&&是否可能不清楚(x?y:z&&w)?对我来说,JS 的操作顺序如何处理这一点并不明显,我想知道您是否可以通过使用 if/else 来理解相同的逻辑和推理?
      【解决方案6】:

      您可以使用Array.prototype.reduce() 创建一个hash 对象,其中keys 是数组中的数字,values 将是arr 数组变量中重复出现的数字。

      然后使用Object.keys():

      • 删除所有重复的Object.keys(hash)
      • 删除所有重复项,但使用 Array.prototype.filter() 过滤以获取仅出现一次的数字

      代码:

      const arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];
      const hash = arr.reduce((a, c) => (a[c] = (a[c] || 0) + 1, a), {});
      
      // [1, 2, 3, 4, 5, 8, 9, 10];
      const finalResultOne = Object.keys(hash);
      
      // [1, 9, 10];
      const finalResultTwo = Object.keys(hash).filter(k => hash[k] === 1);
      
      console.log('finalResultOne:', ...finalResultOne);
      console.log('finalResultTwo:', ...finalResultTwo);

      【讨论】:

        【解决方案7】:

        您可以先对数组进行排序,然后通过仅检查一侧或两侧是否有重复来过滤数组。

        var array = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10],
            result1,
            result2;
        
        array.sort((a, b) => a - b);
        
        result1 = array.filter((v, i, a) => a[i - 1] !== v);
        result2 = array.filter((v, i, a) => a[i - 1] !== v && a[i + 1] !== v);
        
        console.log(...result1);
        console.log(...result2)

        【讨论】:

        • 感谢result1 a[i - 1] !== v 是怎么回事?
        • a 是数组,i 是实际索引,v 是实际值。它从实际索引之前的索引中获取值,并查看值是否不相等。
        • 啊,好吧,抱歉,它需要value from the index before of the actual index?不知道你的意思是什么
        • 例如,如果数组的值9v,那么前面的值为8
        • 啊好的,谢谢
        【解决方案8】:

        正如许多其他人所说,第一个只是[...new Set(arr)]

        对于第二个,只需过滤掉多次出现的那些:

        const arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];
        
        const count = (arr, e) => arr.filter(n => n == e).length
        
        const unique = arr => arr.filter(e => count(arr, e) < 2)
        
        console.log(unique(arr));

        【讨论】:

          【解决方案9】:

          var arr = [1, 2, 4, 2, 3, 3, 4, 5, 5, 5, 8, 8, 9, 10];
          var map = {};
          var finalResult = [];
          for (var i = 0; i < arr.length; i++) {
            if (!map.hasOwnProperty(arr[i])) {
              map[arr[i]] = true;
              finalResult.push(arr[i]);
            }
          }
          
          //if you need it sorted otherwise it will be in order
          finalResult.sort(function(a, b) {
            return a - b
          });
          
          console.log(finalResult);

          【讨论】:

            猜你喜欢
            • 2020-09-03
            • 2014-11-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-26
            • 2014-11-09
            • 2016-02-24
            相关资源
            最近更新 更多