Math.max und Math.min NaN bei undefiniertem Eintrag

Lesezeit: 4 Minuten

Benutzer-Avatar
Jack the Ripper

Beim Übergeben von Werten an die Math.max oder Math.min Funktion in JavaScript, geben sie jeweils die höchsten und niedrigsten Werte aus der Eingabe zurück.

Wenn jedoch ein undefiniertes Datenelement eingegeben wird, z

Math.max(5,10,undefined);

Das zurückgegebene Ergebnis ist NaN. Gibt es eine einfache Möglichkeit, dies mit JS/jQuery zu beheben?

  • Sie können Ihre eigene Wrapper-Funktion zur Überprüfung schreiben oder einfach selbst implementieren.

    – Alvin Wong

    18. Oktober 2012 um 14:52 Uhr

Benutzer-Avatar
Ich hasse faul

Ich vermute die undefined ist eigentlich eine Variable.

Sie können ersetzen -Infinity für alle NaN Wert, um eine Zahl sicherzustellen.

var foo;

Math.max(5, 10, isNaN(foo) ? -Infinity : foo); // returns 10

Dasselbe Konzept kann auf verwendet werden Math.minaber mit Infinity:

var foo;

Math.min(5, 10, isNaN(foo) ? Infinity : foo); // returns 5

  • Gute Antwort! Es würde nicht schaden, auch die Math.min-Implementierung einzubeziehen.

    – cbayram

    18. Oktober 2012 um 14:57 Uhr

  • Anstatt von isNaN(foo) Sie können verwenden foo == foo Welche ist schneller (Quelle).

    – Florent

    18. Oktober 2012 um 15:19 Uhr

  • Ich verwende die kürzere Form Math.max(5, 10, foo || -Infinity)

    – Doug Reeder

    13. März 2018 um 3:46 Uhr

  • @doug reeder das funktioniert nicht, wenn foo falsch wie 0 ist

    – Tom

    5. Januar 2019 um 9:57 Uhr

  • Ja, wenn 0 der größte Wert sein könnte, müssen Sie die längere Form verwenden.

    – Doug Reeder

    6. Januar 2019 um 14:08 Uhr

Benutzer-Avatar
Vision

Schreibe dein Eigenes max Funktion:

function max() {
    var par = []
    for (var i = 0; i < arguments.length; i++) {
        if (!isNaN(arguments[i])) {
            par.push(arguments[i]);
        }
    }
    return Math.max.apply(Math, par);
}

Oder kürzere Verwendung Array-Filterung:

function max() {
    var args = Array.prototype.slice.call(arguments);
    return Math.max.apply(Math, args.filter(function(val) {
       return !isNaN(val);
    }));
}

Verwendungszweck:

max(5, 10, undefined);   // output: 10

  • Großartig, aber wäre es nicht besser zu verwenden isNaN?

    – Alvin Wong

    18. Oktober 2012 um 14:54 Uhr

  • arguments ist leider kein echtes Array.

    – Yoshi

    18. Oktober 2012 um 14:58 Uhr

  • @Yoshi Stimmt. Das habe ich vergessen. Vielen Dank!

    – Vision

    18. Oktober 2012 um 14:59 Uhr

  • @AlvinWong Toller Fang. Vielen Dank!

    – Vision

    18. Oktober 2012 um 15:00 Uhr

  • Du könntest benutzen Array.prototype.slice.call(arguments).filter .... 😉

    – Yoshi

    18. Oktober 2012 um 15:00 Uhr

Benutzer-Avatar
TechWeisheit

Es ist so einfach wie:

// ES6 (returns: 10)
Math.max(...[5, 10, undefined].filter(Number.isFinite))

Oder:

// ES5 (returns: 10)
Math.max.apply(null, [5, 10, undefined].filter(Number.isFinite))

Ich denke, es ist lesbar und vermittelt einfach seinen Zweck.

Erläuterung: Wir nutzen die Number primitive wrapper objectum die undefinierten Werte herauszufiltern und dann an die zu übergeben Math.max Funktion, als Argumente mit der Spread-Operator in ES6, oder mit der Function.prototype.apply() Methode in ES5.

  • Number.isInteger(0.2) ist falsch, daher ist dieser Ansatz mit jeder Dezimalzahl unzuverlässig, z Math.max([0, 0.2].filter(Number.isInteger)). Versuchen Number.isFinite stattdessen.

    – Garrett

    20. Januar 2021 um 1:36 Uhr


  • @Garrett, ich hatte dies am Ende meiner Antwort erwähnt, aber dank Ihres Kommentars habe ich es nach oben verschoben, sodass es jetzt klarer ist. Vielen Dank

    – TechWeisheit

    20. Januar 2021 um 10:48 Uhr

Überprüfen Sie, ob jede Nummer definiert ist, bevor Sie sie an übergeben max. Verwenden Sie einen Sentinel-Wert als Standard (z -Infinity). Für min würden Sie verwenden möchten Infinity:

var a = 5;
var b = 10;
var c = undefined;

var defaultForMax = function (num) {
    return typeof num === 'number' ? num : -Infinity;
};

c = defaultForMax(c); // c is now -Infinity

Math.max(a, b, c); // 10

http://jsfiddle.net/QTckE/

Noch einfacher meiner Meinung nach, wenn es Ihnen nichts ausmacht, d3 zu verwenden, könnten Sie Folgendes tun:

d3.max([5,10,undefined]) // 10

Aus der d3-Dokumentation (https://github.com/d3/d3-array#statistics):

Gibt den Mindestwert in der angegebenen Iterable in natürlicher Reihenfolge zurück.

Anders als das eingebaute Math.min ignoriert diese Methode undefinierte, Null- und NaN-Werte; Dies ist nützlich, um fehlende Daten zu ignorieren. Außerdem werden Elemente in natürlicher Reihenfolge statt in numerischer Reihenfolge verglichen. Zum Beispiel das Minimum der Saiten [“20”, “3”] ist „20“, während das Minimum der Zahlen [20, 3] ist 3.

Benutzer-Avatar
Wahyudiansyah Arif

mit falsy in Math.max

var foo;

Math.max(5, 10, !isNaN(foo) && foo);
var foo;

Math.min(5, 10, !isNaN(foo) && foo);

Benutzer-Avatar
Garrett

// Returns largest numeric value; excludes NaN's.
function getMax(...args) {
 return Math.max(...args.filter(Number.isFinite));
}

  • Während dieser Code die Frage beantworten kann, würde die Bereitstellung von zusätzlichem Kontext dazu, wie und/oder warum er das Problem löst, den langfristigen Wert der Antwort verbessern. Bitte lesen Sie die Tour und Wie schreibe ich eine gute Antwort?

    – Mhd Alaa Alhaj

    20. Januar 2021 um 9:23 Uhr

1019850cookie-checkMath.max und Math.min NaN bei undefiniertem Eintrag

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy