1
votes

For et Foreach boucle et retour avec Set. Premier nombre récurrent dans le tableau

Ma question concerne le résultat de retour de ces boucles. Voici mon code. La fonction doit accepter le tableau comme entrée et y retourner le premier nombre récurrent. J'ai décidé d'utiliser l'objet Set ici.

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

Dans un premier cas avec la boucle forEach, tout fonctionne très bien, je peux console.log à la fois Set et el et je peux le voir, mais il renvoie undefined pour une raison quelconque.

Dans un deuxième cas avec for in loop, tout fonctionne également mais il renvoie en fait la valeur.

Y a-t-il une grande différence entre ces boucles en cas de mot-clé de retour ? Que me manque-t-il?


1 commentaires

La fonction .forEach () ignore complètement les valeurs renvoyées par la fonction de rappel.


4 Réponses :


2
votes

Dans le cas de l'utilisation de forEach , vous passez une fonction anonyme. Dans ce cadre, le retour quittera cette fonction forEach et votre fonction wrapper récurrente continuera d'exécuter le code ci-dessous.

Dans le deuxième exemple, vous ne créez pas une autre fonction, le retour s'applique donc à la fonction récurrente .


0 commentaires

2
votes

Vous devez retourner quelque chose dans la fonction et vous devez prendre find au lieu de forEach , car le dernier ne respecte aucune valeur de retour.

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));


0 commentaires

2
votes

En fait, le problème avec .forEach () méthode est que sa fonction callback renvoie toujours undefined , même si vous utilisez un return .

Si vous cochez la case forEach () method MDN reference vous pouvez voir que:

forEach () exécute la fonction de rappel une fois pour chaque élément du tableau; contrairement à map () ou reduction () il renvoie toujours la valeur undefined et n'est pas chaînable . p >

Donc, dans votre cas, return el; à l'intérieur de forEach () le rappel est toujours ignoré, et à l'intérieur du rappel forEach return est spécifique à cette portée, c'est pourquoi la fonction ne retournera rien.

Solution:

Si vous voulez le faire avec forEach () , ce que vous pouvez faire est de stocker cet drapeau dans une variable afin de pouvoir le renvoyer après le forEach () block:

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));

Démo:

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;
}


0 commentaires

0
votes

Une autre approche, gardez les choses simples:

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


1 commentaires

Vous augmentez le temps d'exécution en effectuant une deuxième recherche dans le tableau. O (n) contre O (n²)