【问题标题】:Find the first repeated number in a Javascript array在 Javascript 数组中查找第一个重复的数字
【发布时间】:2023-03-10 03:06:01
【问题描述】:

我需要找到前两个数字并显示如下索引:

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

所以第一个重复的数字是2,所以变量firstIndex的值应该是0。我必须使用for循环。

var numbers = [7, 5, 7, 6, 6, 4, 9, 10, 2, 11];
var firstIndex

for (i = numbers[0]; i <= numbers.length; i++) {
  firstIndex = numbers[0]
  if (numbers[i] == firstIndex) {
    console.log(firstIndex);
    break;
  }
}

【问题讨论】:

  • 数字范围有限制吗?
  • @Bálint - 老师说他们必须使用“for”循环... ;o)
  • 在您的第一个示例中,我看到的第一个重复数字是 5!

标签: javascript arrays


【解决方案1】:

您可以将Array#indexOf 方法与fromIndex 参数一起使用。

var numbers = [7, 5, 7, 6, 6, 4, 9, 10, 2, 11];

// iterate upto the element just before the last
for (var i = 0; i < numbers.length - 1; i++) {
  // check the index of next element
  if (numbers.indexOf(numbers[i], i + 1) > -1) {
    // if element present log data and break the loop
    console.log("index:", i, "value: ", numbers[i]);
    break;
  }
}


更新: 使用对象来引用元素的索引会更好。

var numbers = [7, 5, 7, 6, 6, 4, 9, 10, 2, 11],
  ref = {};

// iterate over the array
for (var i = 0; i < numbers.length; i++) {
  // check value already defined or not
  if (numbers[i] in ref) {
    // if defined then log data and brek loop
    console.log("index:", ref[numbers[i]], "value: ", numbers[i]);
    break;
  }
  // define the reference of the index
  ref[numbers[i]] = i;
}

【讨论】:

  • 这将是 O(n^2) 运行时
  • 这个错了,结果无效,为什么要投票无效代码?
  • @LukasLiesis Pranav 记录了索引而不是编号。这就是您看到错误输出的原因。请检查我的编辑
  • object.hasOwnProperty() 在当前的 JS 代码中几乎不需要key in object 测试也足够了
【解决方案2】:

很多很好的答案.. 也可以按如下方式在功能上和高效地完成这项工作;

var arr = [2,5,5,2,3,5,1,2,4],
   frei = arr.findIndex((e,i,a) => a.slice(i+1).some(n => e === n)); // first repeating element index
console.log(frei)

If 可能会被证明是有效的,因为 .findIndex().some() 函数都会在满足条件后立即终止。

【讨论】:

  • 这将非常昂贵。 findIndex + slice + some
【解决方案3】:

您可以使用两个for 循环检查每个值每个值。如果发现重复值,则迭代停止。

此提案使用labeled statement 来打破外循环。

var numbers = [1, 3, 6, 7, 5, 7, 6, 6, 4, 9, 10, 2, 11],
    i, j;

outer: for (i = 0; i < numbers.length - 1; i++) {
    for (j = i + 1; j < numbers.length; j++) {
        if (numbers[i] === numbers[j]) {
            console.log('found', numbers[i], 'at index', i, 'and', j);
            break outer;
        }
    }
} 

【讨论】:

  • 你能解释一下外层函数是做什么的吗?
  • outer 是以下循环语句的标签。这个想法是在找到结果时停止两个for 循环。第一个迭代数组,第二个检查数组其余部分是否等于外部元素的元素。内部for 循环的 startinf 索引比外部循环索引大一,因为它防止比较同一索引处的项目。
【解决方案4】:

遍历每个项目并查找是否在不同索引上找到相同的项目,如果是,则它是重复的,只需将其保存到重复变量并中断循环

var numbers = [7, 5, 7, 6, 6, 4, 9, 10, 2, 11];
var duplicate = null;
for (var i = 0; i < numbers.length; i++) {
  if (numbers.indexOf(numbers[i]) !== i) {
    duplicate = numbers[i];
    break; // stop cycle 
  }
}
console.log(duplicate);

【讨论】:

    【解决方案5】:

    var numbers = [7, 5, 7, 6, 6, 4, 9, 10, 2, 11];
    var map = {};
        
    for (var i = 0; i < numbers.length; i++) {
       if (map[numbers[i]] !== undefined) {
           console.log(map[numbers[i]]);
           break;
       } else {
           map[numbers[i]] = i;
       }
    }

    好的,让我们分解一下。我们在这里所做的是创建一个数字映射到它们第一次出现的索引。因此,当我们遍历数字数组时,我们检查它是否在我们的数字映射中。如果是,我们已经找到它并在我们的地图中返回该键的值。否则,我们将数字作为键添加到我们的映射中,它指向它第一次出现的索引。我们使用映射的原因是它非常快 O(1),所以我们的整体运行时间是 O(n),这是在未排序数组上执行此操作的最快速度。

    【讨论】:

      【解决方案6】:

      作为替代方案,您可以使用indexOflastIndexOf,如果值不同,则存在多次重复,您可以中断循环;

      function getFirstDuplicate(arr) {
        for (var i = 0; i < arr.length; i++) {
          if (arr.indexOf(arr[i]) !== arr.lastIndexOf(arr[i])) 
            return arr[i];
        }
      }
      
      var arrWithNumbers = [2, 5, 5, 2, 3, 5, 1, 2, 4];
      console.log(getFirstDuplicate(arrWithNumbers))
      
      var numbers = [1, 3, 6, 7, 5, 7, 6, 6, 4, 9, 10, 2, 11]
      console.log(getFirstDuplicate(numbers))

      【讨论】:

        【解决方案7】:

        我有同样的任务并想出了这个非常基本的解决方案:

        var arr = [7,4,2,4,5,1,6,8,9,4];
        var firstIndex = 0;
        
        for(var i = 0; i < arr.length; i++){
          for( var j = i+1; j < arr.length; j++){
            if(arr[i] == arr[j]){
              firstIndex = arr[i];
              break;      
            }
        
          }
        }
        console.log(firstIndex);
        

        第一个 for 循环从数组中获取第一个元素(编号 7),然后另一个 for 循环检查所有其他元素,等等。

        这里重要的是在第二个循环中定义 ji+1,否则,任何元素都会在相同的索引和 firstIndex 处找到相同的数字 将在所有循环完成后获得最后一个的值。

        【讨论】:

        • 这似乎有时有效,有时无效。有人对此有意见吗?
        • 它只显示最后一个有重复的数字,所以它只有在数组中有一对相等的数字时才有效
        【解决方案8】:

        为了降低上述答案的时间复杂度,您可以使用以下解决方案:

        function getFirstRecurringNumber(arrayOfNumbers) {
          const hashMap = new Map();
        
          for (let number of arrayOfNumbers) { // Time complexity: O(n)
            const numberDuplicatesCount = hashMap.get(number);
        
            if (numberDuplicatesCount) {
              hashMap.set(number, numberDuplicatesCount + 1);
        
              continue;
            }
        
            hashMap.set(number, 1); // Space complexity: O(n)
          }
        
          for (let entry of hashMap.entries()) { // Time complexity: O(i)
            if (entry[1] > 1) {
              return entry[0];
            }
          }
        }
        
        // Time complexity: O(n + i) instead of O(n^2)
        // Space complexity: O(n)
        

        【讨论】:

          【解决方案9】:

          使用下面的代码,我可以得到数组中出现的第一个“5”。 .some() 方法一旦找到匹配项就会停止循环。

          let james = [5, 1, 5, 8, 2, 7, 5, 8, 3, 5];
          let onlyOneFives = [];
          james.some(item =>  {
              //checking for a condition. 
              if(james.indexOf(item) === 0) {
                  //if the condition is met, then it pushes the item to a new array and then   
                  //returns true which stop the loop
          
                  onlyOneFives.push(item);
                   return james.indexOf(item) === 0;
             }
          })
          
          console.log(onlyOneFives)
          

          【讨论】:

            【解决方案10】:

            创建一个带有数字的数组的函数,在其中执行以下操作: 首先,实例化一个空对象。 其次,创建一个 for 循环,遍历数组的每个元素,并为每个元素添加它们到空对象并检查对象的长度是否已更改,如果没有,则意味着您添加了一个已经存在的元素所以你可以退货:

            //Return first recurring number of given array, if there isn't return undefined.
            
            const firstRecurringNumberOf = array =>{
                objectOfArray = {};
            
                for (let dynamicIndex = 0; dynamicIndex  < array.length; dynamicIndex ++) {
                    const elementsBeforeAdding = (Object.keys(objectOfArray)).length;0
                    objectOfArray[array[dynamicIndex]] = array[dynamicIndex]
                    const elementsAfterAdding = (Object.keys(objectOfArray)).length;
            
                    if(elementsBeforeAdding == elementsAfterAdding){ //it means that the element already existed in the object, so it didnt was added & length doesnt change.
                         return array[dynamicIndex];
                    }
                }
            
                return undefined;
            }
            
            console.log(firstRecurringNumberOf([1,2,3,4])); //returns undefined
            console.log(firstRecurringNumberOf([1,4,3,4,2,3])); //returns 4
            

            【讨论】:

              【解决方案11】:
              var addIndex = [7, 5, 2, 3, 4, 5, 7,6, 2];
              var firstmatch = [];
              for (var i = 0; i < addIndex.length; i++) {
              
                  if ($.inArray(addIndex[i], firstmatch) > -1) {
                      return false;
                  }
                  firstmatch.push(addIndex[i]);
              }
              

              【讨论】:

              • 缺少第一个解释。其次,您可以将firstIndex 初始化为numbers[0] 并从1 开始循环。也不确定这是否能正常工作
              • 请在数组开头添加1,然后重新运行。您的算法仅检查第一个元素。
              • 你可以编辑然后编辑和更改它..如果我做错了什么
              • 请查看其他答案。 Pranav 的回答显示了 2 个非常好的方法。您可以查看我的答案以了解替代方法。无需包含任何库即可完成此任务
              • 通常最好在您的帖子中添加解释代码如何工作的说明。这使新开发人员能够了解代码的作用。
              猜你喜欢
              • 2015-08-23
              • 1970-01-01
              • 1970-01-01
              • 2017-09-22
              • 2017-01-04
              • 2021-07-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多