J'ai construit une fonction qui vous permet de passer à travers un tableau et qui renvoie avec succès les deuxième et deuxième chiffres les plus élevés. Cependant, je suis nouveau dans la gestion des erreurs et je ne comprends pas pourquoi cela échoue:

getNos([5,"5",8]);

Il fonctionne correctement lors de la transmission de getNos([5,5,8]); ou en passant des tableaux comme getNos(["5",8]);.

Quelqu'un peut-il expliquer ce qui se passe ici et comment y remédier? Merci pour toute aide ici - le code de fonction est ci-dessous:

function getNos(arr){

if (!Array.isArray(arr) || arr.length == 0 || arr.length == 1 || (arr.every(c => !isNaN(c)) == false)) {
    throw 'Invalid Input';
} else {

    var result;
    var uniqueVals = Array.from(new Set(arr));
    var highest = highestVal(arr);
    var lowest = lowestVal(arr);

    if (uniqueVals.length == 1) {
        result = arr[0] + " " + arr[0];
    } else if (arr.length == 2 || uniqueVals.length == 2) {
        result = highest + " " + lowest;
    } else {
        arr = arr.filter(item => ((item !== highest) && (item !== lowest)));
        var secondHighest = highestVal(arr);
        var secondLowest = lowestVal(arr);

        if (arr.length == 1) {
            arr = arr.slice(arr.indexOf(secondHighest));
            result = highestVal(arr);
        } else {
            result = secondLowest + " " + secondHighest;
        }
    }
    return result;
}

function highestVal(a) { return a.reduce((a, b) => a > b ? a : b ) };
function lowestVal(a) { return a.reduce((a, b) => a < b ? a : b ) };
}
0
user8758206 19 nov. 2018 à 18:36

3 réponses

Meilleure réponse

Suivez attentivement la logique var uniqueVals = Array.from(new Set(arr)). Que renverra cette ligne lorsque vous aurez des tableaux tels que [5,"5",8] vs [5,5,8] vs ["5", 8]?

Un Set stocke la valeur unique d'un type. "5" est de type string tandis que 5 est de type number. Les fonctions highestVal et lowestVal peuvent comparer "5" et 8, pas de problème, mais comme un tableau peut inclure soit un string ou number pour 5 ou 8 également, vous obtiendrez alors des valeurs amusantes.

Pour résoudre ce problème, avant de passer de arr à Set, vous devez convertir toutes les valeurs en un seul type, de préférence number.

let numberArr = arr.map(el=>+el) est une façon de le faire, mais vous voudrez peut-être une meilleure validation des données que cela.

3
wlh 19 nov. 2018 à 15:46

La fonction n'échoue pas dans le sens où elle renvoie une erreur. Pour ces types de questions, veuillez ajouter un exemple de "résultats attendus".

Lorsque vous comparez des chaînes et des nombres en JavaScript, vous comptez sur la contrainte implicite pour effectuer la comparaison. Dans ce cas, il ne lancera pas d'erreur et ne cassera rien, c'est bien car JavaScript convertira votre chaîne en nombre et comparera (sauf si c'est une stricte égalité === qui vérifie également le type).

Le résultat doit-il être basé sur ce qui a été transmis? Ou après que l'entrée a été filtrée pour les nombres uniquement. Ou si l'entrée peut être convertie en nombres valides?

Dans le cas d'un filtre pour les numéros valides. Filtrez l'entrée comme suit ...

  arr = arr.filter(data => typeof data === 'number')

Dans le cas de la conversion de valeurs en nombre et de la suppression de celles qui ne peuvent pas être converties ...

  arr = arr.reduce(((acc, el) => {
                       const num = Number(el);
                       if (!Number.isNaN(num)) acc.push(num);
                       return acc;
                     }), []);
1
Sunny Wong 19 nov. 2018 à 16:25

Une solution simple serait de mapper les valeurs aux nombres avant de créer l'ensemble pour éviter d'avoir les mêmes valeurs numériques que la chaîne et le nombre dans l'ensemble

Changement

var uniqueVals = Array.from(new Set(arr));

À

var uniqueVals = Array.from(new Set(arr.map(Number)));
1
charlietfl 19 nov. 2018 à 15:51