Min / Max von Daten in einem Array?

106

Wie kann ich das minimale und das maximale Datum aus einer Reihe von Daten herausfinden? Derzeit erstelle ich ein Array wie folgt:

var dates = [];
dates.push(new Date("2011/06/25"))
dates.push(new Date("2011/06/26"))
dates.push(new Date("2011/06/27"))
dates.push(new Date("2011/06/28"))

Gibt es eine eingebaute Funktion, um dies zu tun, oder soll ich meine eigene schreiben?

Legende
quelle

Antworten:

136

Code wird mit IE, FF, Chrome getestet und funktioniert ordnungsgemäß:

var dates=[];
dates.push(new Date("2011/06/25"))
dates.push(new Date("2011/06/26"))
dates.push(new Date("2011/06/27"))
dates.push(new Date("2011/06/28"))
var maxDate=new Date(Math.max.apply(null,dates));
var minDate=new Date(Math.min.apply(null,dates));
Andrew D.
quelle
1
Die Umrechnung von Zahlen wurde nicht für die Zeichenfolge '2011/06/25', sondern für das neue Datum ('2011/06/25') angewendet. Nummer (neues Datum ('2011/06/25')) === 1308949200000. Code wird in Chrome, IE, FF
Andrew D.
@RobG - Was meinst du mit "String-Daten"?
Andrew D.
zB dates.push('2011/06/05'). Mithilfe von Zeichenfolgen kann das Array einfach sortiert und der erste und letzte Elementwert zurückgegeben und bei Bedarf in Datumsangaben konvertiert werden.
RobG
10
@RobG - in der obigen Frage enthält das Array Datumsobjekte, keine "Datumszeichenfolgen" - Antwort auch für Datumsobjekte. Die Verwendung von "Datumszeichenfolgen" ist in einigen Fällen eine sehr schlechte Praxis. Vergleichen Sie die nächsten beiden Datumszeichenfolgen: "2011/06/05" und "2011/06/05 00:00:00". 1) als Zeichenfolgen: ("2011/06/05" === "2011/06/05 00:00:00"): Ergebnis ist falsch; 2) als Datumsobjekte (mit Konvertierung in Nummer): Nummer (neues Datum ("05.06.2011")) === Nummer (neues Datum ("05.06.2011 00:00:00")): Ergebnis ist wahr - ist ein richtiges Ergebnis!
Andrew D.
@ AndrewD. Wenn die dateStrings beispielsweise konsistent sind YYYY/MM/DD HH:MM:SSund viele Zeichenfolgen beteiligt sind, würden Sie einen Zeichenfolgenvergleich oder Number(new Date(dateString))Vergleiche empfehlen ?
BlackPanther
83

Etwas wie:

var min = dates.reduce(function (a, b) { return a < b ? a : b; }); 
var max = dates.reduce(function (a, b) { return a > b ? a : b; });

Getestet auf Chrome 15.0.854.0 dev


quelle
Array.reduce()vor IE9 nicht im IE verfügbar. Coole Idee.
jfriend00
1
Array.reduce () kann mit Javascript-Äquivalentfunktion implementiert werden
Andrew D.
Genau, lesen Sie darüber in Eloquent Javascript :function foreach(func, array) { for(var i = 0; i != array.length; ++i) { func(array[i]); } } function reduce(combine, base, array) { foreach(function(element) { base = combine(base, element); }, array); return base; }
Blaze
1
IE <9 kann sterben, und tatsächlich macht es ab April 2013 nur noch 9,3% der weltweiten Browsernutzung aus.
wprl
3
Die Reduktionslösung funktioniert für Zeichenfolgen- und Datumsobjekte.
Benoit
33

_.minund _.maxarbeiten an Arrays von Daten; Verwenden Sie diese, wenn Sie Lodash oder Unterstrich verwenden, und erwägen Sie die Verwendung von Lodash (das viele solche Dienstprogrammfunktionen bietet), falls Sie dies noch nicht getan haben.

Beispielsweise,

_.min([
    new Date('2015-05-08T00:07:19Z'),
    new Date('2015-04-08T00:07:19Z'),
    new Date('2015-06-08T00:07:19Z')
])

gibt das zweite Datum im Array zurück (da es das früheste ist).

Mark Amery
quelle
3
Beantwortet die Frage von OP nicht direkt. OP fragt, ob eine integrierte Methode in JavaScript verfügbar ist. Also, obwohl _.min & _.max verwendet werden kann, um minimale oder maximale Daten zu finden, ist dies nicht das, wonach das OP sucht. Auch die Berücksichtigung einer Utility-Bibliothek ist ein Thema mit einer Meinung.
Detj
13
Ich bin respektvoll anderer Meinung und denke, dass dies eine nützliche Antwort ist, @detj - die Frage des OP, wie sie derzeit formuliert ist, setzt voraus, dass entweder eine eingebaute Funktion vorhanden ist oder er seine eigene schreiben muss, aber dies ist nicht wahr. Es erscheint mir vernünftig, Utility-Bibliotheken als Alternative zu den vom OP vorgeschlagenen Lösungen hervorzuheben. Aber Ihre Argumentation ist vertretbar und Ihre Stimme ist Ihre eigene.
Mark Amery
16

Gleich wie gelten, jetzt mit Spread :

const maxDate = new Date(Math.max(...dates));

(könnte ein Kommentar zur besten Antwort sein)

lvd
quelle
12

Da Datumsangaben in die UNIX-Epoche (Zahlen) konvertiert werden, können Sie Math.max / min verwenden, um diese zu finden:

var maxDate = Math.max.apply(null, dates)
// convert back to date object
maxDate = new Date(maxDate)

(nur in Chrome getestet, sollte aber in den meisten Browsern funktionieren)

Ricardo Tomasi
quelle
8

** Verwenden Sie Spread-Operatoren | ES6 **

let datesVar = [ 2017-10-26T03:37:10.876Z,
  2017-10-27T03:37:10.876Z,
  2017-10-23T03:37:10.876Z,
  2015-10-23T03:37:10.876Z ]

Math.min(...datesVar);

Das gibt das Mindestdatum aus dem Array an.

Die Kurzform Math.min.apply (null, ArrayOfdates);

Rudresh Ajgaonkar
quelle
1
Wenn Sie abstimmen, kommentieren Sie bitte. Warum ist das eine schlechte Option? Ich mag die Syntax und für kleine Arrays ist der Leistungsverlust vernachlässigbar.
GijsjanB
1
Ich wurde abgelehnt. Rudreshs Antwort ist ein Duplikat von mir oben. Keine Ahnung, warum die Leute das nicht mögen. Es ist eine einzelne Codezeile im Vergleich zu vielen Zeilen.
2
Dies gibt eine Zahl zurück, die kein Datum ist, sodass Sie sie wieder in ein Datum konvertieren müssen. Aber sonst ist es ziemlich elegant.
Tomáš Hübelbauer
6

ONELINER :

var min= dates.sort((a,b)=>a-b)[0], max= dates.slice(-1)[0];

führt in Variablen minund die maxKomplexität O (n log n) , editierbare Beispiel hier . Wenn Ihr Array keine Datumswerte (wie null) hat, bereinigen Sie es zuerst mit dates=dates.filter(d=> d instanceof Date);.

Kamil Kiełczewski
quelle
2
var max_date = dates.sort(function(d1, d2){
    return d2-d1;
})[0];
wong2
quelle
1

Die obigen Antworten behandeln keine leeren / undefinierten Werte, um dies zu beheben. Ich habe den folgenden Code verwendet und Leerzeichen durch NA ersetzt:

function getMax(dateArray, filler) {
      filler= filler?filler:"";
      if (!dateArray.length) {
        return filler;
      }
      var max = "";
      dateArray.forEach(function(date) {
        if (date) {
          var d = new Date(date);
          if (max && d.valueOf()>max.valueOf()) {
            max = d;
          } else if (!max) {
            max = d;
          }
        }
      });
      return max;
    };
console.log(getMax([],"NA"));
console.log(getMax(datesArray,"NA"));
console.log(getMax(datesArray));

function getMin(dateArray, filler) {
 filler = filler ? filler : "";
  if (!dateArray.length) {
    return filler;
  }
  var min = "";
  dateArray.forEach(function(date) {
    if (date) {
      var d = new Date(date);
      if (min && d.valueOf() < min.valueOf()) {
        min = d;
      } else if (!min) {
        min = d;
      }
    }
  });
  return min;
}

console.log(getMin([], "NA"));
console.log(getMin(datesArray, "NA"));
console.log(getMin(datesArray));

Ich habe hier eine einfache Javascript- Demo hinzugefügt und sie als Filter mit AngularJS in diesem Codepen verwendet

Samdeesh
quelle
0

Dies ist eine besonders gute Möglichkeit, dies zu tun (Sie können mit einer der Objekteigenschaften maximal ein Array von Objekten abrufen): Math.max.apply(Math,array.map(function(o){return o.y;}))

Dies ist die akzeptierte Antwort für diese Seite: Ermitteln des Maximalwerts eines Attributs in einem Array von Objekten


quelle
-2

Verwenden von Moment , Unterstrich und jQuery , um eine Reihe von Daten zu iterieren.

Beispiel JSON:

"workerList": [{        
        "shift_start_dttm": "13/06/2017 20:21",
        "shift_end_dttm": "13/06/2017 23:59"
    }, {
        "shift_start_dttm": "03/04/2018 00:00",
        "shift_end_dttm": "03/05/2018 00:00"        
    }]

Javascript:

function getMinStartDttm(workerList) {  
    if(!_.isEmpty(workerList)) {
        var startDtArr = [];
        $.each(d.workerList, function(index,value) {                
            startDtArr.push(moment(value.shift_start_dttm.trim(), 'DD/MM/YYYY HH:mm')); 
         });            
         var startDt = _.min(startDtArr);           
         return start.format('DD/MM/YYYY HH:mm');
    } else {
        return '';
    }   
}

Ich hoffe es hilft.

Siva Anand
quelle