Comment trier un tableau par une propriété de date

698

Disons que j'ai un tableau de quelques objets:

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

Comment puis-je trier ce tableau par l'élément date dans l'ordre à partir de la date la plus proche de la date et de l'heure actuelles? Gardez à l'esprit que le tableau peut contenir de nombreux objets, mais pour des raisons de simplicité, j'ai utilisé 2.

Vais-je utiliser la fonction de tri et un comparateur personnalisé?

MISE À JOUR:

Dans mon cas particulier, je voulais que les dates soient arrangées du plus récent au plus ancien. Il s'est avéré que j'ai dû inverser la logique de la fonction simple comme suit:

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

Cela trie les dates des plus récentes.

ryandlf
la source
Si vous utilisez le constructeur Date, consultez ce premier stackoverflow.com/questions/5619202/…
ohkts11
le moyen le plus rapide consiste à utiliser le module de tableau de tri isomorphe qui fonctionne nativement dans le navigateur et le nœud, prenant en charge tout type d'entrée, les champs calculés et les ordres de tri personnalisés.
Lloyd

Réponses:

1404

Réponse la plus simple

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

Réponse plus générique

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

Ou plus laconiquement:

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

Réponse générique et puissante

Définissez une sortByfonction non énumérable personnalisée à l'aide d'une transformation Schwartzian sur tous les tableaux:

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

Utilisez-le comme ceci:

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

Si votre date n'est pas directement comparable, faites-en une date comparable, par exemple

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

Vous pouvez également l'utiliser pour trier selon plusieurs critères si vous retournez un tableau de valeurs:

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

Voir http://phrogz.net/JS/Array.prototype.sortBy.js pour plus de détails.

Phrogz
la source
2
Pourquoi tout simplement pas return b-a;dans la réponse simple?
corbacho
19
Nous vous déconseillons de créer de nouveaux objets Date dans la méthode de tri. Ont rencontré des problèmes de performances de production spécifiquement pour cette raison. N'allouez pas de mémoire (et GC) à l'intérieur d'une méthode de tri.
MikeMurko
4
la première syntaxe, par exemple, donne une erreur sur angular7: le côté gauche d'une opération arithmétique doit être de type 'any', 'number', 'bigint' ou de type enum
SURENDRANATH SONAWANE
1
@MikeMurko qu'avez-vous fait pour y remédier?
Sireini
@SURENDRANATHSONAWANE convertir la date en horodatage Unix: renvoyer la nouvelle date (b.date) .getTime () - nouvelle date (a.date) .getTime ();
Robert Ostrowicki,
147

Les réponses @Phrogz sont excellentes, mais voici une excellente réponse, plus concise:

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

Utilisation de la fonction de flèche

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

trouvé ici: Trier la date en Javascript

Fille
la source
15
Faire le calcul directement a - bfonctionnerait également. Donc, array.sort((a, b) => a - b)(es6)
yckart
C'est une bonne solution lors de l'utilisation de Typescript.
maartenpaauw
72

Après avoir corrigé le JSON, cela devrait fonctionner pour vous maintenant:

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
la source
45

Vos données nécessitent quelques corrections:

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

Après avoir corrigé les données, vous pouvez utiliser ce morceau de code:

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);​
gabitzish
la source
Pour tous ceux qui utilisent Typescript, j'ai pu trier par date en utilisant cette fonction, tandis que les autres utilisant la soustraction de date ont échoué.
Danchat
24

Je recommande GitHub: Array sortBy - une meilleure implémentation de sortByméthode qui utilise la transformation Schwartzian

Mais pour l'instant nous allons essayer cette approche Gist: sortBy-old.js .
Créons une méthode pour trier les tableaux pouvant arranger les objets selon une propriété.

Création de la fonction de tri

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

}());

Définition de données non triées

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"}
];

En l'utilisant

Enfin, nous organisons le tableau, par "date"propriété commestring

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

Si vous souhaitez ignorer la casse des lettres, définissez le "parser"rappel:

//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();
    }
});

Si vous souhaitez traiter le champ "date" comme du Datetype:

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

Ici, vous pouvez jouer avec l'exemple ci-dessus:
jsbin.com/lesebi

jherax
la source
1
IE11 a eu un problème avec la ligne: if (toString.call (cfg)! == "[Object object]") cfg = {}; Si vous le remplacez par if (Object.prototype.toString.call (cfg)! == "[object object]") cfg = {}; vous serez également très bien avec IE11.
skribbz14
1
Excellente solution
Moses Machua
14

Cela devrait être fait lorsque votre date est dans ce format (jj / mm / aaaa).

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

    return arr;
  }

Appelez ensuite sortByDate(myArr);

Edison D'souza
la source
12

Vous pouvez utiliser sortBy dans le soulignement js.

http://underscorejs.org/#sortBy

Échantillon:

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
la source
Le moyen parfait et le plus court de le faire!
Bhavik Kalariya
8

Je vais ajouter ceci ici, car certaines utilisations peuvent ne pas être en mesure de déterminer comment inverser cette méthode de tri.

Pour trier par "venir", nous pouvons simplement échanger a & b, comme ceci:

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

Notez que ac'est maintenant sur le côté gauche, et bsur la droite,: D!

James111
la source
7

J'utilise personnellement l'approche suivante pour trier les dates.

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
la source
6

j'ai pu réaliser le tri en utilisant les lignes ci-dessous:

array.sort(function(a, b)
{
   if (a.DueDate > b.DueDate) return 1;
   if (a.DueDate < b.DueDate) return -1;
})
Amay Kulkarni
la source
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
la source
2

Pour tous ceux qui souhaitent trier par date (format UK), j'ai utilisé ce qui suit:

//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;
    }); 
}
Et moi
la source
2

Je viens de prendre la transformée schwartzienne représentée ci-dessus et faite comme fonction. Il faut un array, le tri functionet un booléen en entrée:

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
la source
2

Merci Ganesh Sanap. tri des éléments par champ de date de l'ancien au nouveau. Utilise le

 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;
        });
Янов Алексей
la source
1
Quelle est la raison moins?
Янов Алексей
2

Si comme moi, vous avez un tableau avec des dates formatées comme YYYY[-MM[-DD]]où vous souhaitez commander des dates plus spécifiques avant des dates moins spécifiques, j'ai trouvé cette fonction pratique:

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
la source
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
la source
Veuillez expliquer brièvement votre réponse et vérifier la mise en forme de votre code.
dthulke
Échouera pour les anciennes dates.
Oliver Dixon