J'essaie de pousser uniquement les valeurs du tableau 'eachNumber' avec les index de la variable 'indexes' à l'intérieur du tableau 'appearMost', mais pour une raison quelconque, il retourne un tableau avec des valeurs non définies:

var indexes = [1,2];
var appearMost = [];
var eachNumber = [4, 7, 9, 8];

indexes.map(function(c) { appearMost.push(eachNumber[c]) }); // should return [7,9]

Le résultat d'apparaîtreMost devrait être [7,9].

Étrange, car j'ai construit une fonction qui renvoie le nombre apparaissant le plus souvent dans un tableau qui s'appuie sur la ligne ci-dessus qui ne semble pas fonctionner. Par exemple:

mostAppearing([5,5,2,2,1]); // correctly returns 5
mostAppearing([3,4,1,6,10]); // correctly returns -1
mostAppearing([4,7,7,7,9,9,8]); // correctly returns 7
mostAppearing([4,7,7,9,7,9,9,8]); // correctly returns 9

Et la fonction a le code:

function mostAppearing(arr) { // e.g. var arr = [4,7,7,9,7,9,9,8];

var eachNumber = Array.from(new Set(arr)); // [4, 7, 9, 8];

if (arr.length == eachNumber.length) {
    return -1;
} else {
    var counts = eachNumber.map(function(c){ return arr.filter(function(el){ return el==c }).length }); // [1, 3, 3, 1];
    var maxVolume = Math.max(...counts); // 3
    var volVolume = counts.filter((c) => c == maxVolume).length; // 2

    if (volVolume == 1) {
        return arr[maxVolume];
    } else {
        var indexes = counts.reduce((a, c, i) => (c === maxVolume) ? a.concat(i) : a, []); // [1,2]
        var appearMost = [];
        indexes.map(function(c) { appearMost.push(eachNumber[c]) }); // relies on this line
        return Math.max(...appearMost);
    }
}

}

Quelqu'un peut-il expliquer (1) pourquoi les valeurs non définies sont le résultat plutôt que [7,9], et (2) comment ma fonction fonctionne correctement? Cela devrait échouer. Merci pour toute aide ici.

2
user8758206 20 nov. 2018 à 14:40

3 réponses

Meilleure réponse

La valeur de appearMost est correctement mise à jour.

var indexes = [1,2];
var appearMost = [];
var eachNumber = [4, 7, 9, 8];

indexes.map(function(c) { appearMost.push(eachNumber[c]) })
console.log(appearMost)

Je crois que vous vous attendiez à ce que la valeur de retour de la fonction de carte soit 7,9 au lieu de la valeur à l'intérieur de l'apparence La carte elle-même ne renverra pas de valeur car vous n'avez pas utilisé return dans votre fonction. Une meilleure pratique serait d'avoir le tableau de retour de la fonction map au lieu de muter un tableau existant:

appearMost = indexes.map(function(c) { return eachNumber[c] })
3
Shushan 20 nov. 2018 à 11:51

Mettez à jour votre code comme ci-dessous et vous pouvez obtenir le résultat souhaité. Ici, count contient la valeur en tant qu'objet { data: d, count: d.length }. alors max contiendra le nombre maximal de valeurs répétées. Ensuite, counts objet filtré pour la valeur répétée maximale et sélectionné uniquement data pour mapper dans l'objet appearMost. Valeur maximale renvoyée par appearMost.

function mostAppearing(arr) { // e.g. var arr = [4,7,7,9,7,9,9,8];
  var eachNumber = Array.from(new Set(arr)); // [4, 7, 9, 8];

  if (arr.length == eachNumber.length) {
    return -1;
  } else {
    var counts = eachNumber.map(function(c) {
      var d = arr.filter(el => el == c);
      return { data: d, count: d.length }
    });

    var max = Math.max(...counts.map(x => x.count));
    var appearMost = counts.filter(c => c.count == max).map(x => x.data[0]);

    return Math.max(...appearMost);
  }
}

console.log(mostAppearing([5,5,2,2,1])); // correctly returns 5
console.log(mostAppearing([3,4,1,6,10])); // correctly returns -1
console.log(mostAppearing([4,7,7,7,9,9,8])); // correctly returns 7
console.log(mostAppearing([4,7,7,9,7,9,9,8])); // correctly returns 9
1
Karan 20 nov. 2018 à 12:00

Filtrer l'ensemble du tableau pour chaque élément n'est probablement pas le plus efficace.

Vous pouvez parcourir le tableau une fois avec une réduction en créant une carte qui a l'élément de tableau comme clé et la quantité qu'il se produit comme valeur.

Ensuite, réduisez-le une fois de plus pour obtenir le nombre le plus fréquent et le plus élevé. Je mets la garde du tableau vide et du cas de bord de tous les nombres n'apparaissant qu'une fois (retour -1 dans les deux cas) dans une fonction séparée:

const highestMostAppearing = (arr) =>
  [
    ...arr
      .reduce(
        (result, number) =>
          result.set(number, (result.get(number) || 0) + 1),
        new Map(),
      )
      .entries(),//Map where key is the number and value is the amount of time it occurs
  ].reduce(//this will error with empty array but mostAppearing will guard for that
    //result is highestNumber and mostAppeared so far
    //  item is the number and how many times it appeared
    ([highestNumber, mostAppeared], [number, appears]) =>
      appears > mostAppeared//current item appeared more often than the most appeared so far
        ? [number, appears]//return current number and how many times it appeared
        //next line checks if current number appeared the same times as highest so far
        //  and checks if current number is higher than the highest appeared number
        : appears === mostAppeared && highestNumber < number
          ? [number, appears]//replace result with current item values
          : [highestNumber, mostAppeared],//return previous result (is most appearing and highest)
  );
const mostAppearing = (arr) => {
  if (arr.length === 0) return -1;//do not call highestMostAppearing with empty array
  const [highest, appearing] = highestMostAppearing(arr);
  if (appearing === 1) return -1;//all numbers appear only once (expensive op here)
  return highest;//return most appearing highest nubmber
};

console.log('=======', mostAppearing([5, 5, 2, 2, 1]));
console.log('=======', mostAppearing([]));
0
HMR 20 nov. 2018 à 12:26