So sortieren Sie ein Array nach einer Datumseigenschaft

698

Angenommen, ich habe eine Reihe einiger Objekte:

var array = [{id: 1, date: Mar 12 2012 10:00:00 AM}, {id: 2, date: Mar 8 2012 08:00:00 AM}];

Wie kann ich dieses Array nach dem Datumselement sortieren, ab dem Datum, das dem aktuellen Datum und der aktuellen Uhrzeit am nächsten liegt? Denken Sie daran, dass das Array möglicherweise viele Objekte enthält, aber der Einfachheit halber habe ich 2 verwendet.

Würde ich die Sortierfunktion und einen benutzerdefinierten Komparator verwenden?

AKTUALISIEREN:

In meinem speziellen Fall wollte ich die Daten von den neuesten bis zu den ältesten. Es endete damit, dass ich die Logik der einfachen Funktion wie folgt umkehren musste:

array.sort(function(a, b) {
    a = new Date(a.dateModified);
    b = new Date(b.dateModified);
    return a>b ? -1 : a<b ? 1 : 0;
});

Dadurch werden die Daten der neuesten sortiert.

ryandlf
quelle
Wenn Sie den Datumskonstruktor
ohkts11
Am schnellsten ist es, das isomorphe Sort-Array- Modul zu verwenden, das sowohl im Browser als auch im Knoten nativ funktioniert und jede Art von Eingabe, berechneten Feldern und benutzerdefinierten Sortierreihenfolgen unterstützt.
Lloyd

Antworten:

1402

Einfachste Antwort

array.sort(function(a,b){
  // Turn your strings into dates, and then subtract them
  // to get a value that is either negative, positive, or zero.
  return new Date(b.date) - new Date(a.date);
});

Allgemeinere Antwort

array.sort(function(o1,o2){
  if (sort_o1_before_o2)    return -1;
  else if(sort_o1_after_o2) return  1;
  else                      return  0;
});

Oder knapper:

array.sort(function(o1,o2){
  return sort_o1_before_o2 ? -1 : sort_o1_after_o2 ? 1 : 0;
});

Generische, leistungsstarke Antwort

Definieren Sie eine benutzerdefinierte nicht aufzählbare sortByFunktion mithilfe einer Schwartzschen Transformation für alle Arrays:

(function(){
  if (typeof Object.defineProperty === 'function'){
    try{Object.defineProperty(Array.prototype,'sortBy',{value:sb}); }catch(e){}
  }
  if (!Array.prototype.sortBy) Array.prototype.sortBy = sb;

  function sb(f){
    for (var i=this.length;i;){
      var o = this[--i];
      this[i] = [].concat(f.call(o,o,i),o);
    }
    this.sort(function(a,b){
      for (var i=0,len=a.length;i<len;++i){
        if (a[i]!=b[i]) return a[i]<b[i]?-1:1;
      }
      return 0;
    });
    for (var i=this.length;i;){
      this[--i]=this[i][this[i].length-1];
    }
    return this;
  }
})();

Verwenden Sie es so:

array.sortBy(function(o){ return o.date });

Wenn Ihr Datum nicht direkt vergleichbar ist, machen Sie daraus ein vergleichbares Datum, z

array.sortBy(function(o){ return new Date( o.date ) });

Sie können dies auch verwenden, um nach mehreren Kriterien zu sortieren, wenn Sie ein Array von Werten zurückgeben:

// Sort by date, then score (reversed), then name
array.sortBy(function(o){ return [ o.date, -o.score, o.name ] };

Weitere Informationen finden Sie unter http://phrogz.net/JS/Array.prototype.sortBy.js .

Phrogz
quelle
2
Warum einfach nicht return b-a;in der einfachen Antwort?
Corbacho
19
Es wird nicht empfohlen, neue Datumsobjekte innerhalb der Sortiermethode zu erstellen. Ich habe speziell aus diesem Grund Probleme mit der Produktionsleistung festgestellt. Ordnen Sie keinen Speicher (und GC) innerhalb einer Sortiermethode zu.
Mike Murko
4
Die erste zB Syntax gibt einen Fehler in Winkel7 aus: Die linke Seite einer arithmetischen Operation muss vom Typ 'any', 'number', 'bigint' oder vom Typ enum sein
SURENDRANATH SONAWANE
1
@ MikeMurko Was hast du getan, um das Problem zu beheben?
Sireini
@SURENDRANATHSONAWANE Datum in Unix-Zeitstempel konvertieren: neues Datum (b.date) zurückgeben .getTime () - neues Datum (a.date) .getTime ();
Robert Ostrowicki
147

@ Phrogz Antworten sind beide großartig, aber hier ist eine großartige, präzisere Antwort:

array.sort(function(a,b){return a.getTime() - b.getTime()});

Verwenden der Pfeilfunktion

array.sort((a,b)=>a.getTime()-b.getTime());

hier gefunden: Datum in Javascript sortieren

Gal
quelle
15
Das direkte Rechnen a - bwürde auch funktionieren. Also, array.sort((a, b) => a - b)(es6)
Yckart
Dies ist eine gute Lösung bei Verwendung von Typescript.
Maartenpaauw
72

Nach der Korrektur des JSON sollte dies jetzt für Sie funktionieren:

var array = [{id: 1, date:'Mar 12 2012 10:00:00 AM'}, {id: 2, date:'Mar 8 2012 08:00:00 AM'}];


array.sort(function(a, b) {
    var c = new Date(a.date);
    var d = new Date(b.date);
    return c-d;
});
qw3n
quelle
45

Ihre Daten müssen korrigiert werden:

var array = [{id: 1, date: "Mar 12 2012 10:00:00 AM"},{id: 2, date: "Mar 28 2012 08:00:00 AM"}];

Nach dem Korrigieren der Daten können Sie diesen Code verwenden:

function sortFunction(a,b){  
    var dateA = new Date(a.date).getTime();
    var dateB = new Date(b.date).getTime();
    return dateA > dateB ? 1 : -1;  
}; 

var array = [{id: 1, date: "Mar 12 2012 10:00:00 AM"},{id: 2, date: "Mar 28 2012 08:00:00 AM"}];
array.sort(sortFunction);​
gabitzisch
quelle
Für jeden, der Typescript verwendet, konnte ich mit dieser Funktion nach Datum sortieren, während die anderen, die die Datumssubtraktion verwendeten, fehlschlugen.
Danchat
24

Ich empfehle GitHub: Array sortBy - eine beste Implementierung einer sortByMethode, die die Schwartzsche Transformation verwendet

Aber jetzt werden wir diesen Ansatz versuchen. Gist: sortBy-old.js .
Erstellen wir eine Methode zum Sortieren von Arrays, mit denen Objekte nach einer Eigenschaft angeordnet werden können.

Sortierfunktion erstellen

var sortBy = (function () {
  var toString = Object.prototype.toString,
      // default parser function
      parse = function (x) { return x; },
      // gets the item to be sorted
      getItem = function (x) {
        var isObject = x != null && typeof x === "object";
        var isProp = isObject && this.prop in x;
        return this.parser(isProp ? x[this.prop] : x);
      };

  /**
   * Sorts an array of elements.
   *
   * @param {Array} array: the collection to sort
   * @param {Object} cfg: the configuration options
   * @property {String}   cfg.prop: property name (if it is an Array of objects)
   * @property {Boolean}  cfg.desc: determines whether the sort is descending
   * @property {Function} cfg.parser: function to parse the items to expected type
   * @return {Array}
   */
  return function sortby (array, cfg) {
    if (!(array instanceof Array && array.length)) return [];
    if (toString.call(cfg) !== "[object Object]") cfg = {};
    if (typeof cfg.parser !== "function") cfg.parser = parse;
    cfg.desc = !!cfg.desc ? -1 : 1;
    return array.sort(function (a, b) {
      a = getItem.call(cfg, a);
      b = getItem.call(cfg, b);
      return cfg.desc * (a < b ? -1 : +(a > b));
    });
  };

}());

Unsortierte Daten einstellen

var data = [
  {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0,   type: "cash"},
  {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
  {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"},
  {date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0,   type: "cash"}
];

Es benutzen

Schließlich ordnen wir das Array nach "date"Eigenschaft alsstring

//sort the object by a property (ascending)
//sorting takes into account uppercase and lowercase
sortBy(data, { prop: "date" });

Wenn Sie die Groß- und Kleinschreibung ignorieren möchten, legen Sie den "parser"Rückruf fest:

//sort the object by a property (descending)
//sorting ignores uppercase and lowercase
sortBy(data, {
    prop: "date",
    desc: true,
    parser: function (item) {
        //ignore case sensitive
        return item.toUpperCase();
    }
});

Wenn Sie das Feld "Datum" als DateTyp behandeln möchten :

//sort the object by a property (ascending)
//sorting parses each item to Date type
sortBy(data, {
    prop: "date",
    parser: function (item) {
        return new Date(item);
    }
});

Hier können Sie mit dem obigen Beispiel spielen:
jsbin.com/lesebi

Jherax
quelle
1
IE11 hatte ein Problem mit der Zeile: if (toString.call (cfg)! == "[Objekt Objekt]") cfg = {}; Wenn Sie es durch if ersetzen (Object.prototype.toString.call (cfg)! == "[object Object]") cfg = {}; Sie werden auch alle gut mit IE11 sein.
skribbz14
1
Ausgezeichnete Lösung
Moses Machua
14

Dies sollte geschehen, wenn Ihr Datum in diesem Format vorliegt (TT / MM / JJJJ).

  sortByDate(arr) {
    arr.sort(function(a,b){
      return Number(new Date(a.readableDate)) - Number(new Date(b.readableDate));
    });

    return arr;
  }

Dann ruf an sortByDate(myArr);

Edison D'souza
quelle
12

Sie können sortBy in Unterstrichen verwenden.

http://underscorejs.org/#sortBy

Stichprobe:

var log = [{date: '2016-01-16T05:23:38+00:00', other: 'sample'}, 
           {date: '2016-01-13T05:23:38+00:00',other: 'sample'}, 
           {date: '2016-01-15T11:23:38+00:00', other: 'sample'}];

console.log(_.sortBy(log, 'date'));
Robert
quelle
Perfekter und kürzester Weg!
Bhavik Kalariya
8

Ich werde dies hier hinzufügen, da einige Verwendungen möglicherweise nicht in der Lage sind, herauszufinden, wie diese Sortiermethode invertiert werden kann.

Um nach "Kommen" zu sortieren, können wir einfach a & b wie folgt tauschen:

your_array.sort ( (a, b) => {
      return new Date(a.DateTime) - new Date(b.DateTime);
});

Beachten Sie, dass asich das jetzt auf der linken Seite und bauf der rechten Seite befindet: D!

James111
quelle
7

Ich persönlich verwende den folgenden Ansatz, um Daten zu sortieren.

let array = ["July 11, 1960", "February 1, 1974", "July 11, 1615", "October 18, 1851", "November 12, 1995"];

array.sort(function(date1, date2) {
   date1 = new Date(date1);
   date2 = new Date(date2);
   if (date1 > date2) return 1;
   if (date1 < date2) return -1;
})
Aravinda Meewalaarachchi
quelle
6

Ich konnte die Sortierung anhand der folgenden Zeilen erreichen:

array.sort(function(a, b)
{
   if (a.DueDate > b.DueDate) return 1;
   if (a.DueDate < b.DueDate) return -1;
})
Amay Kulkarni
quelle
5
Adding absolute will give better results

var datesArray =[
      {"some":"data1","date": "2018-06-30T13:40:31.493Z"},
      {"some":"data2","date": "2018-07-04T13:40:31.493Z"},
      {"some":"data3","date": "2018-06-27T13:40:54.394Z"}
   ]

var sortedJsObjects = datesArray.sort(function(a,b){ 
    return Math.abs(new Date(a.date) - new Date(b.date)) 
});
Rajiv Shrivastava
quelle
2

Für alle, die nach Datum sortieren möchten (UK-Format), habe ich Folgendes verwendet:

//Sort by day, then month, then year
for(i=0;i<=2; i++){
    dataCourses.sort(function(a, b){

        a = a.lastAccessed.split("/");
        b = b.lastAccessed.split("/");

        return a[i]>b[i] ? -1 : a[i]<b[i] ? 1 : 0;
    }); 
}
Und ich
quelle
2

Ich habe gerade die oben abgebildete Schwartzsche Transformation genommen und als Funktion gemacht. Es wird ein array, die Sortierung functionund ein Boolescher Wert als Eingabe verwendet:

function schwartzianSort(array,f,asc){
    for (var i=array.length;i;){
      var o = array[--i];
      array[i] = [].concat(f.call(o,o,i),o);
    }
    array.sort(function(a,b){
      for (var i=0,len=a.length;i<len;++i){
        if (a[i]!=b[i]) return a[i]<b[i]?asc?-1:1:1;
      }
      return 0;
    });
    for (var i=array.length;i;){
      array[--i]=array[i][array[i].length-1];
    }
    return array;
  }

function schwartzianSort(array, f, asc) {
  for (var i = array.length; i;) {
    var o = array[--i];
    array[i] = [].concat(f.call(o, o, i), o);
  }
  array.sort(function(a, b) {
    for (var i = 0, len = a.length; i < len; ++i) {
      if (a[i] != b[i]) return a[i] < b[i] ? asc ? -1 : 1 : 1;
    }
    return 0;
  });
  for (var i = array.length; i;) {
    array[--i] = array[i][array[i].length - 1];
  }
  return array;
}

arr = []
arr.push({
  date: new Date(1494434112806)
})
arr.push({
  date: new Date(1494434118181)
})
arr.push({
  date: new Date(1494434127341)
})

console.log(JSON.stringify(arr));

arr = schwartzianSort(arr, function(o) {
  return o.date
}, false)
console.log("DESC", JSON.stringify(arr));

arr = schwartzianSort(arr, function(o) {
  return o.date
}, true)
console.log("ASC", JSON.stringify(arr));

loretoparisi
quelle
2

Vielen Dank, dass Sie Ganesh Sanap. Sortieren von Elementen nach Datumsfeld von alt nach neu. Benutze es

 myArray = [{transport: "Air",
             load: "Vatican Vaticano",
             created: "01/31/2020"},
            {transport: "Air",
             load: "Paris",
             created: "01/30/2020"}] 

        myAarray.sort(function(a, b) {
            var c = new Date(a.created);
            var d = new Date(b.created);
            return c-d;
        });
Янов Алексей
quelle
1
Was ist der Grund minus?
31нов Алексей
2

Wenn Sie wie ich ein Array mit Datumsangaben haben, die so formatiert sind, YYYY[-MM[-DD]]dass Sie spezifischere Daten vor weniger bestimmten bestellen möchten, habe ich diese praktische Funktion entwickelt:

function sortByDateSpecificity(a, b) {
  const aLength = a.date.length
  const bLength = b.date.length
  const aDate = a.date + (aLength < 10 ? '-12-31'.slice(-10 + aLength) : '')
  const bDate = b.date + (bLength < 10 ? '-12-31'.slice(-10 + bLength) : '')
  return new Date(aDate) - new Date(bDate)
}
Daviestar
quelle
0
["12 Jan 2018" , "1 Dec 2018", "04 May 2018"].sort(function(a,b) {
    return new Date(a).getTime() - new Date(b).getTime()
})
Shravan Shetty
quelle
Bitte erläutern Sie kurz Ihre Antwort und überprüfen Sie die Formatierung Ihres Codes.
Dthulke
Wird für alte Daten scheitern.
Oliver Dixon