【问题标题】:Checking for duplicate strings in JavaScript array检查 JavaScript 数组中的重复字符串
【发布时间】:2018-08-19 07:12:14
【问题描述】:

我有带字符串的 JS 数组,例如:

var strArray = [ "q", "w", "w", "e", "i", "u", "r"];

我需要比较数组中的重复字符串,如果存在重复字符串,应该有指向该字符串的警告框。

我试图将它与for 循环进行比较,但我不知道如何编写代码,以便数组检查自己的字符串是否重复,而无需预先确定要比较的字符串。

【问题讨论】:

  • 连续重复,或任何类型的重复?如果你在最后扔了另一个“q”,那应该算作重复吗?
  • 任何类型的重复。它可以在数组的中间,也可以在数组的末尾,或者任何其他组合。
  • 在我的测试中,最快的方法是this one

标签: javascript arrays compare


【解决方案1】:

您必须创建一个空数组,然后检查给定数组的每个元素,如果新数组已经包含它会提醒您的元素。 像这样的。

  var strArray = [ "q", "w", "w", "e", "i", "u", "r"];
  let newArray =[];
  function check(arr){
  for(let elements of arr){
  if(newArray.includes(elements)){
  alert(elements)
  }
 else{
 newArray.push(elements);
 }
 }
 return newArray.sort();
  }
check(strArray);

【讨论】:

    【解决方案2】:

    使用 ES6 功能

    • 因为Set 中的每个值都必须是唯一的,所以将检查值是否相等。

    function checkIfDuplicateExists(arr) {
        return new Set(arr).size !== arr.length
    }
      
    var arr = ["a", "a", "b", "c"];
    var arr1 = ["a", "b", "c"];
    
    console.log(checkIfDuplicateExists(arr)); // true
    console.log(checkIfDuplicateExists(arr1)); // false

    【讨论】:

      【解决方案3】:
       const isDuplicate = (str) =>{
         return new Set(str.split("")).size === str.length;
      }
      

      【讨论】:

      • 你能解释一下为什么这行得通吗?由于这个问题相当古老,因此最好清楚地说明它为什么有用。
      • 上述方法是一个谓词方法,意味着只返回布尔值。由于 set 只取唯一值,因此我将字符串拆分为字符数组,然后将字符数组解析为 set 构造函数以删除任何重复字符。这意味着如果字符数组中存在重复项,则该集合将包含唯一的,之后我将原始字符串的长度与集合大小进行比较。如果长度相同,则表示没有重复,否则表示存在。
      【解决方案4】:

      您可以使用Set 并过滤到已经看到的值。

      var array = ["q", "w", "w", "e", "i", "u", "r"],
          seen = array.filter((s => v => s.has(v) || !s.add(v))(new Set));
      
      console.log(seen);

      【讨论】:

        【解决方案5】:

        function hasDuplicates(arr) {
            var counts = [];
        
            for (var i = 0; i <= arr.length; i++) {
                if (counts[arr[i]] === undefined) {
                    counts[arr[i]] = 1;
                } else {
                    return true;
                }
            }
            return false;
        }
        
        // [...]
        
        var arr = [1, 1, 2, 3, 4];
        
        if (hasDuplicates(arr)) {
          alert('Error: you have duplicates values !')
        }

        简单的 Javascript(如果你不懂 ES6)

        function hasDuplicates(arr) {
            var counts = [];
        
            for (var i = 0; i <= arr.length; i++) {
                if (counts[arr[i]] === undefined) {
                    counts[arr[i]] = 1;
                } else {
                    return true;
                }
            }
            return false;
        }
        
        // [...]
        
        var arr = [1, 1, 2, 3, 4];
        
        if (hasDuplicates(arr)) {
          alert('Error: you have duplicates values !')
        }
        

        【讨论】:

          【解决方案6】:

          这是我猜的最简单的解决方案:

          function diffArray(arr1, arr2) {
            return arr1
              .concat(arr2)
              .filter(item => !arr1.includes(item) || !arr2.includes(item));
          }
          

          【讨论】:

            【解决方案7】:
            var strArray = [ "q", "w", "w", "e", "i", "u", "r", "q"];
            var alreadySeen = [];
            
            strArray.forEach(function(str) {
              if (alreadySeen[str])
                alert(str);
              else
                alreadySeen[str] = true;
            });
            

            我从您的原始文件中添加了另一个副本,只是为了表明它会找到一个不连续的副本。

            带有箭头功能的更新版本:

            const strArray = [ "q", "w", "w", "e", "i", "u", "r", "q"];
            const alreadySeen = [];
            
            strArray.forEach(str => alreadySeen[str] ? alert(str) : alreadySeen[str] = true);
            

            【讨论】:

            • 这个解决方案也很好用!谢谢。很遗憾我也不能接受(绿色复选标记)你的回答。
            • 不错的一个。这种特殊的逻辑很容易允许“任何”行为(也就是说,当我发现有任何重复时,我可以将循环短路)。
            • 我可以澄清一下吗?上面的表达式alreadySeen[str] = true 是否只是将str 项添加到alreadySeen 数组中?和alreadySeen.push(str)一样吗?
            • @BenClarke,不,因为推送词添加str作为数组的元素,而alreadySeen[str] = true添加str作为数组的索引,使用数组作为哈希表.此处可以使用Set 对象,可能更清晰。
            • @kshetline 好的,谢谢您的澄清。不过,这对我来说有点太高级了:) 这种方法有什么特别的名称吗?我想了解更多有关它的信息
            【解决方案8】:

            findDuplicates 函数(如下)将数组中所有项目的索引与相同项目第一次出现的索引进行比较。如果索引不同,则将其返回为重复。

            let strArray = [ "q", "w", "w", "w", "e", "i", "u", "r"];
            let findDuplicates = arr => arr.filter((item, index) => arr.indexOf(item) != index)
            
            console.log(findDuplicates(strArray)) // All duplicates
            console.log([...new Set(findDuplicates(strArray))]) // Unique duplicates

            【讨论】:

            • 这不会返回唯一的数组,如果在数组中重复多次,则重复项将被包含多次。以xxxyyyxxx 为例。
            【解决方案9】:

            你可以使用reduce:

            const arr = ["q", "w", "w", "e", "i", "u", "r"]
            arr.reduce((acc, cur) => { 
              if(acc[cur]) {
                acc.duplicates.push(cur)
              } else {
                acc[cur] = true //anything could go here
              }
            }, { duplicates: [] })
            

            结果如下所示:

            { ...Non Duplicate Values, duplicates: ["w"] }
            

            这样你就可以对重复的值做任何你想做的事情!

            【讨论】:

              【解决方案10】:
                 var elems = ['f', 'a','b','f', 'c','d','e','f','c'];
              
                  elems.sort();
              
                  elems.forEach(function (value, index, arr){
              
                      let first_index = arr.indexOf(value);
                      let last_index = arr.lastIndexOf(value);
              
                       if(first_index !== last_index){
              
                       console.log('Duplicate item in array ' + value);
              
                       }else{
              
                       console.log('unique items in array ' + value);
              
                       }
              
                  });
              

              【讨论】:

                【解决方案11】:

                在处理大数组时使用对象键以获得良好的性能(在这种情况下,循环每个元素并再次循环检查重复将非常缓慢)。

                var strArray = ["q", "w", "w", "e", "i", "u", "r"];
                
                var counting = {};
                strArray.forEach(function (str) {
                    counting[str] = (counting[str] || 0) + 1;
                });
                
                if (Object.keys(counting).length !== strArray.length) {
                    console.log("Has duplicates");
                
                    var str;
                    for (str in counting) {
                        if (counting.hasOwnProperty(str)) {
                            if (counting[str] > 1) {
                                console.log(str + " appears " + counting[str] + " times");
                            }
                        }
                    }
                }
                

                【讨论】:

                  【解决方案12】:

                  在数组上使用 some 函数: 如果数组中的任何项从开头的索引号不等于从结尾的索引号,则该项在数组中存在多次。

                  // vanilla js
                  function hasDuplicates(arr) {
                      return arr.some( function(item) {
                          return arr.indexOf(item) !== arr.lastIndexOf(item);
                      });
                  }
                  

                  【讨论】:

                  • 嗨,你的函数是我需要的(只返回一个布尔值)但我不知道 ES6,你能用“简单”的 javascript 写吗?
                  猜你喜欢
                  • 2016-02-12
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-03-27
                  • 2020-08-07
                  • 2018-11-28
                  • 2015-10-20
                  • 2020-11-21
                  • 1970-01-01
                  相关资源
                  最近更新 更多