Min / Max dat w tablicy?

107

Jak mogę znaleźć minimalną i maksymalną datę z tablicy dat? Obecnie tworzę tablicę taką:

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

Czy jest do tego wbudowana funkcja, czy mam napisać własną?

Legenda
źródło

Odpowiedzi:

137

Kod jest testowany z IE, FF, Chrome i działa poprawnie:

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.
źródło
1
Konwersja liczb nie dotyczyła ciągu „2011/06/25”, ale nowej daty („2011/06/25”). Numer (nowa data ('2011/06/25')) === 1308949200000. Kod jest testowany w Chrome, IE, FF
Andrew D.
@RobG - Co rozumiesz przez „daty w postaci ciągów”?
Andrew D.
np dates.push('2011/06/05'). Używając łańcuchów, tablicę można po prostu posortować, a wartości pierwszego i ostatniego elementu członkowskiego mogą zostać zwrócone i w razie potrzeby przekonwertowane na daty.
RobG
10
@RobG - w powyższym pytaniu tablica zawiera obiekty Date, a nie „stringi daty” - odpowiedź również na obiekty Date. W niektórych przypadkach używanie „ciągów daty” jest bardzo złą praktyką. Porównaj następne dwa ciągi dat: „2011/06/05” i „2011/06/05 00:00:00”. 1) jako ciągi: ("2011/06/05" === "2011/06/05 00:00:00"): wynik jest fałszywy; 2) jako obiekty Date (z konwersją na numer): Number (new Date ("2011/06/05")) === Number (new Date ("2011/06/05 00:00:00")): wynik jest prawdą - to dobry wynik!
Andrew D.
@AndrewD. Jeśli łańcuchy dateStrings są spójne, powiedzmy, że w grę wchodzi YYYY/MM/DD HH:MM:SSdużo ciągów, czy poleciłbyś porównanie ciągów lub Number(new Date(dateString))porównania?
BlackPanther
84

Coś jak:

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

Testowane w Chrome 15.0.854.0 dev


źródło
Array.reduce()niedostępne w IE przed IE9. Fajny pomysł.
jfriend00
1
Array.reduce () można zaimplementować za pomocą funkcji równoważnej javascript
Andrew D.
Dokładnie, przeczytaj o tym w 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 może umrzeć, a obecnie stanowi tylko 9,3% globalnego wykorzystania przeglądarek od kwietnia 2013 r.
wprl
3
Rozwiązanie redukujące działa dla obiektów typu string i Dates.
Benoit
33

_.mini _.maxpracuj na tablicach dat; użyj ich, jeśli używasz Lodash lub Underscore, i rozważ użycie Lodash (który zapewnia wiele takich funkcji narzędziowych), jeśli jeszcze nie jesteś.

Na przykład,

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

zwróci drugą datę w tablicy (ponieważ jest najwcześniejsza).

Mark Amery
źródło
3
Nie odpowiada bezpośrednio na pytanie OP. OP pyta, czy w JavaScript jest dostępna wbudowana metoda. Tak więc, chociaż _.min i _.max można użyć do znalezienia dat minimalnych lub maksymalnych, ale nie jest to tym, czego szuka OP. Również rozważenie biblioteki narzędziowej jest tematem upartym.
detj
13
Z całym szacunkiem nie zgadzam się i uważam, że to użyteczna odpowiedź, @detj - pytanie OP w obecnym brzmieniu zakłada, że ​​albo jest wbudowana funkcja, albo musi napisać własną, ale to nieprawda. Wydaje mi się rozsądne wskazanie bibliotek narzędziowych jako alternatywy dla któregokolwiek z proponowanych rozwiązań PO. Ale twoje rozumowanie jest do obrony, a twój głos należy do ciebie.
Mark Amery,
16

Tak samo jak w przypadku zastosowania, teraz z rozszerzeniem :

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

(może to być komentarz do najlepszej odpowiedzi)

lvd
źródło
12

Ponieważ daty są konwertowane na epoki UNIX (liczby), możesz użyć Math.max / min, aby je znaleźć:

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

(testowane tylko w Chrome, ale powinno działać w większości przeglądarek)

Ricardo Tomasi
źródło
8

** Użyj operatorów rozprzestrzeniania | 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);

To da minimalną datę z tablicy.

Jego skrót Math.min.apply (null, ArrayOfdates);

Rudresh Ajgaonkar
źródło
1
Jeśli głosujesz przeciw, prosimy o komentarz. Dlaczego to zła opcja? Podoba mi się składnia, a dla małych tablic spadek wydajności jest znikomy.
GijsjanB
1
Zostałem odrzucony. Odpowiedź Rudresha jest kopią mojej powyżej. Nie mam pojęcia, dlaczego ludziom się to nie podoba. To pojedyncza linia kodu w porównaniu z wieloma liniami.
3
Zwraca liczbę, a nie datę, więc musisz przekonwertować ją z powrotem na datę. Ale poza tym jest całkiem elegancki.
Tomáš Hübelbauer
6

ONELINER :

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

wynik w postaci zmiennych mini maxzłożoności O (nlogn) , przykład do edycji tutaj . Jeśli twoja tablica nie ma wartości dat (takich jak null), najpierw ją wyczyść dates=dates.filter(d=> d instanceof Date);.

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

Powyższe odpowiedzi nie obsługują pustych / niezdefiniowanych wartości, aby to naprawić. Użyłem poniższego kodu i zamieniłem puste miejsca na NA:

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

Dodałem tutaj zwykłe demo javascript i użyłem go jako filtru z AngularJS w tym codepen

Samdeesh
źródło
0

Jest to szczególnie świetny sposób na zrobienie tego (możesz uzyskać maksymalną tablicę obiektów za pomocą jednej z właściwości obiektu): Math.max.apply(Math,array.map(function(o){return o.y;}))

To jest akceptowana odpowiedź dla tej strony: Znajdowanie maksymalnej wartości atrybutu w tablicy obiektów


źródło
-2

Używanie Moment , Underscore i jQuery do iteracji tablicy dat.

Przykładowy 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 '';
    }   
}

Mam nadzieję, że to pomoże.

Siva Anand
źródło