За и цикл по каждому элементу и возврат с Set.Первый повторяющийся номер в массиве - PullRequest
1 голос
/ 26 сентября 2019

Мой вопрос касается результата возврата из этих циклов.Вот мой кодФункция должна принимать массив в качестве входных данных и возвращать первый повторяющийся номер в нем.Я решил использовать Set object здесь.

const arr1 = [2, 2, 3, 2, 5, 6, 6, 9]; 

  const recurring = (arr) => {

    const set = new Set();

    // This returns undefined
    arr.forEach(el => {
      if (set.has(el)) {
        return el;
      } else {
        set.add(el); 
      }   
    })       

    // This returns 2
    for (let el in arr) {
     if (set.has(arr[el])) {
       return arr[el];
     } else {
       set.add(arr[el]); 
     }   
    } 

  }

    recurring(arr1); // Should return 2

В первом случае с циклом forEach все работает отлично, я могу console.log и Set, и el, и я вижу его, но для некоторых он возвращает undefinedпричина.

Во втором случае с циклом for все также работает, но на самом деле возвращает значение.

Есть большая разница между этими циклами в случае ключевого слова return?Чего мне не хватает?

Ответы [ 4 ]

2 голосов
/ 26 сентября 2019

Вам нужно вернуть что-то в функцию, и вам нужно взять find вместо forEach, потому что последнее не учитывает никакого возвращаемого значения.

const arr1 = [2, 2, 3, 2, 5, 6, 6, 9];

const recurring = (arr) => {
    const set = new Set();
    return arr.find(el => {
        if (set.has(el)) return true;
        set.add(el);
    });
};

console.log(recurring(arr1));
2 голосов
/ 26 сентября 2019

На самом деле проблема с .forEach() методом заключается в том, что его функция callback всегда возвращает undefined, даже если вы используете оператор return.

Если вы проверите ссылку * MD1 метода MDN , вы увидите, что:

forEach() выполняет функцию обратного вызова один раз для каждого массиваэлемент;в отличие от map() или reduce() он всегда возвращает значение undefined и не является цепным .

Так что в вашем случае return el; внутри forEach() обратный вызов всегдаигнорируется, и внутри forEach обратного вызова return является специфическим для этой области, поэтому function ничего не возвращает.

Решение:

Есливы хотите сделать это с forEach(), вы можете сохранить это flag в переменной, чтобы вы могли вернуть его после блока forEach():

const recurring = (arr) => {

  const set = new Set();
  let result;
  arr.forEach(el => {
    if (set.has(el)) {
       result = !result ? el : result;
      return;
    } else {
      set.add(el);
    }
  });
  return result;
}

Demo:

const arr1 = [2, 2, 3, 2, 5, 6, 6, 9];

const recurring = (arr) => {

  const set = new Set();
  let result;

  arr.forEach(el => {
    if (set.has(el)) {
      result = !result ? el : result;
      return;
    } else {
      set.add(el);
    }
  });
  return result;
}

console.log(recurring(arr1));
2 голосов
/ 26 сентября 2019

В случае использования forEach вы передаете анонимную функцию.В пределах этой области, возврат завершит работу этой функции forEach, а ваша функция-обертка recurring продолжит выполнение приведенного ниже кода.

Во втором примере вы не создаете другую функцию, поэтому возврат применяется кфункция recurring.

0 голосов
/ 26 сентября 2019

Другой подход, будьте проще:

const recurring = (arr) => {
    for(let r = 0; r < arr.length; r++){
        if(arr.indexOf(arr[r],r+1)>-1)return arr[r];
    }
}
...