突破 JavaScript ES6 函数不适用于 return

Break out of JavaScript ES6 function not working with return

问题

这感觉应该很简单,但出于某种原因我就是不明白。我决定接受一个看似常见的编程面试问题来测试我的技能:

"Given an array a that contains only numbers in the range from 1 to a.length, find the first duplicate number for which the second occurrence has the minimal index. In other words, if there are more than 1 duplicated numbers, return the number for which the second occurrence has a smaller index than the second occurrence of the other number does."

(来源:https://codefights.com/interview-practice/task/pMvymcahZ8dY4g75q

我相信我有正确的代码,但我无法让循​​环停止 运行。给定示例数组,函数应该 return "3",因为这是第一个重复的数字(不是第一个看到的数字)。但是,无论我尝试什么,它要么是 returns 2 要么是错误。

我的代码

console.clear();

// create new object to store numbers and counts
var myObj = {};

// array for testing output
var arr1 = [2, 3, 3, 1, 5, 2];

// this will store the "key" number
var firstDuplicateFound = "";

function firstDup(a) {

 // loop through each value in numerical array
 a.forEach(function(num, i) {
  
  // if associative array has property that is value of current num:
  if ( myObj.hasOwnProperty(num) ) {
   
   // increment value by 1
   ++myObj[num];
   
   firstDuplicateFound = num;
   // If first duplicate is found, the code should jump out of the
   // loop and return from the function. It should NOT continue
   // to process the code in the forEach. At one point, I tried
   // "return firstDuplicateFound" here, but it just returned 2.
   
  } else {

   // create new array key and assign count of 1
   myObj[num] = 1;
   
  }

  if (firstDuplicateFound && firstDuplicateFound != NaN) {
   return firstDuplicateFound;
  }
  
 });

 console.log(myObj);
 
 return false;
 
}

var firstDupNumberFound = firstDup(arr1);

console.log("firstDupNumberFound = " + firstDupNumberFound);

我尝试过但没有奏效的方法

我已经尝试了所有我能想到的。我阅读了 breakcontinue 之间的区别,并尝试在分配 firstDuplicateFound = num 后立即使用 "break",但它只是给出我关于“​​非法中断语句”的错误:

Uncaught SyntaxError: Illegal break statement at Array.forEach () at firstDup (:15:4) at :49:27 firstDup @ VM80757:15 (anonymous) @ VM80757:49

我尝试将 break 移动到其他位置,但我读到的所有内容都说 break 仅在循环内有效。

然后我深入挖掘,发现几篇文章指出 return 是退出的正确语句功能。当找到第一个重复项时,我希望循环停止执行并退出函数并 return "num" 的值,而不处理数字数组的其余部分。这不会发生。我已经在不同的位置尝试了 returnreturn firstDuplicateFoundreturn false

我查阅的链接

我的问题

  1. 我做错了什么,我如何获得 return 找到的第一个重复项的代码?

  2. 我对完成这项工作的理解缺少什么? "return firstDuplicateFound" 不应该是最好的解决方案吗?我真的很想深入了解如何正确执行此操作。

编辑

Stack Overflow 问我是否 (this post, the one you are reading) is a duplicate of ,如果我不同意,要我解释为什么不。 这不是重复的 - 尽管提供了类似的答案,而且另一个问题的发帖人似乎正在解决 similar 问题 - 因为我的问题是关于根本不起作用的东西,而另一个问题是关于优化已经起作用的东西。

此外,正在寻找 "why doesn't this work" 的人不太可能看到 "how to optimize ..." 并认为这与他们有关。一个东西必须先工作,然后才能开始优化它。

您是 returnforeach 函数中的 ig 值。为数组中的每个元素调用此函数,它的 return 值被忽略。

而不是 .forEach() 使用 for loop 和 return。

console.clear();

// create new object to store numbers and counts
var myObj = {};

// array for testing output
var arr1 = [2, 3, 3, 1, 5, 2];

// this will store the "key" number
var firstDuplicateFound = "";

function firstDup(a) {

 // loop through each value in numerical array
    for (let i =0; i <a.length; i++) {
  const num = a[i]
  // if associative array has property that is value of current num:
  if ( myObj.hasOwnProperty(num) ) {
   
   // increment value by 1
   ++myObj[num];
   
   firstDuplicateFound = num;
   // If first duplicate is found, the code should jump out of the
   // loop and return from the function. It should NOT continue
   // to process the code in the forEach. At one point, I tried
   // "return firstDuplicateFound" here, but it just returned 2.
   
  } else {

   // create new array key and assign count of 1
   myObj[num] = 1;
   
  }

  if (firstDuplicateFound && firstDuplicateFound != NaN) {
   return firstDuplicateFound;
  }
  
 }

 console.log(myObj);
 
 return false;
 
}

var firstDupNumberFound = firstDup(arr1);

console.log("firstDupNumberFound = " + firstDupNumberFound);

哪里出了问题 :

您根本无法从 forEach 循环中 return/exit。而已。因此,如果您想编写命令式代码而不是函数式代码(通过使用 breakcontinuereturn),您应该使用简单的旧式 for 循环:

  function firstDup(array) {
     //A hashtable to check for dupes
     const hash = {};
     // loop through each value in numerical array
    for(var n of array){
      if(n in hash){
        return n;
      } else {
       hash[n] = true;
      }
    }
    return false;
 }

我的做法:

据我了解

return the number for which the second occurrence has a smaller index than the second occurrence of the other number does

就意味着return第一个骗子

这很简单:

 function dupe(array){
  return array.find((n,i) => array.indexOf(n) !== i);
 }

或使用一组:

function dupe(array){
  const set = new Set;
  return array.find(n => set.has(n) || (set.add(n), false));
}

您可以在不检查 ownProperty 的情况下使用散列 table,因为潜在的键总是真实的,不需要直接检查其他键。

散列 table 的值只是 true,因为不需要其他值,例如计数或其他真值。

此提议使用一种快速方法,为

取变量
  • 索引i,
  • 数组的长度l
  • 数组 a 的一个元素,无需进一步使用 属性 访问器。

为了提高速度,一个简单的 while 循环与 if 子句一起工作,用于检查元素是否已被访问。

如果访问了return值,否则设置哈希并继续。

function firstDupe(array) {
    var hash = Object.create(null),
        i = 0,
        l = array.length,
        a;

    while (i < l) {
        a = array[i++];
        if (hash[a]) {
            return a;
        }
        hash[a] = true;
    }
}

console.log(firstDupe([2, 3, 3, 1, 5, 2]));

好的我的版本

const numbers = [1, 3, 7, 1, 0, 8, 7, 2, 3, 7, 1, 4, 4, 7];

const duplicateMap = numbers
    .map((n, i) => {
    const index = numbers.findIndex(r => r === n);
    return index === i ? null : index;
  });


let last = null;
let result = null;

duplicateMap.forEach((n, i) => {
    if (n !== null && (last === null || i < last)) {
    result = n;
  }

  last = n !== null ? i : last;
}); 


console.log(numbers,  duplicateMap, result);

Input: [1, 3, 7, 1, 0, 8, 7, 2, 3, 7, 1, 4, 4, 7]
dupMap:[null, null, null, 0, null, null, 2, null, 1, 2, 0, null, 11, 2]
Result: 0