Hoe sorteer ik een objectarray op datumeigenschap?

Stel dat ik een array van een paar objecten heb:

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

Hoe kan ik deze array sorteren op het date-element in volgorde van de datum die het dichtst bij de huidige datum en tijd ligt? Houd er rekening mee dat de array veel objecten kan hebben, maar voor de eenvoud heb ik 2 gebruikt.

Zou ik de sorteerfunctie en een aangepaste vergelijker gebruiken?


Antwoord 1, autoriteit 100%

Eenvoudigste antwoord

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

Meer algemeen antwoord

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

Of nog beknopter:

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

Algemeen, krachtig antwoord

Definieer een aangepaste niet-opsombare sortBy-functie met behulp van een Schwartziaanse transformatieop 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;
  }
})();

Gebruik het als volgt:

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

Als je date niet direct vergelijkbaar is, maak er dan een vergelijkbare date van, bijvoorbeeld

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

U kunt dit ook gebruiken om op meerdere criteria te sorteren als u een reeks waarden retourneert:

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

Zie http://phrogz.net/JS/Array.prototype.sortBy.jsvoor meer details.


Antwoord 2, autoriteit 12%

@Phrogz-antwoorden zijn allebei geweldig, maar hier is een geweldig, beknopter antwoord:

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

De pijlfunctie gebruiken

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

hier gevonden: Sorteer datum in Javascript


Antwoord 3, autoriteit 5%

Na het corrigeren van de JSON zou dit nu voor u moeten werken:

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

Antwoord 4, autoriteit 3%

Uw gegevens hebben enkele correcties nodig:

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

Na het corrigeren van de gegevens, kunt u dit stukje code gebruiken:

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

Antwoord 5

Ik raad GitHub: Array sortByaan – een beste implementatie van sortBymethode die gebruik maakt van de Schwartziaanse transformatie

Maar voor nu gaan we deze aanpak proberen Gist: sortBy-old.js.
Laten we een methode maken om arrays te sorteren, zodat we objecten kunnen rangschikken op een eigenschap.

De sorteerfunctie maken

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

Ongesorteerde gegevens instellen

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

Het gebruiken

Ten slotte rangschikken we de array, op "date"eigenschap als string

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

Als u kleine letters wilt negeren, stelt u de "parser"terugbelopdracht in:

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

Als u het veld “datum” wilt behandelen als Date, typt u:

//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 kun je spelen met het bovenstaande voorbeeld:
jsbin.com/lesebi


Antwoord 6

Dit zou moeten gebeuren als je datum in dit formaat is (dd/mm/jjjj).

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

Bel vervolgens sortByDate(myArr);


Antwoord 7

Je zou sortBy kunnen gebruiken in underscore js.

http://underscorejs.org/#sortBy

Voorbeeld:

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

Antwoord 8

Ik ga dit hier toevoegen, omdat sommige gebruikers er misschien niet in slagen deze sorteermethode om te keren.

Om te sorteren op ‘coming up’, kunnen we eenvoudig een & b, zoals zo:

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

Merk op dat anu aan de linkerkant is, en baan de rechterkant, :D!


Antwoord 9

Ik gebruik persoonlijk de volgende benadering om datums te sorteren.

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

Antwoord 10

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

Antwoord 11

ik kon sorteren met onderstaande regels:

array.sort(function(a, b)
{
   if (a.DueDate > b.DueDate) return 1;
   if (a.DueDate < b.DueDate) return -1;
})

Antwoord 12

Met ES6-pijlfuncties kunt u verder slechts één regel beknopte code schrijven (exclusief variabele declaratie).

Bijvoorbeeld:

var isDescending = true; //set to false for ascending
console.log(["8/2/2020","8/1/2020","8/13/2020", "8/2/2020"].sort((a,b) => isDescending ? new Date(b).getTime() - new Date(a).getTime() : new Date(a).getTime() - new Date(b).getTime()));

Antwoord 13

Bedankt Ganesh Sanap. items sorteren op datumveld van oud naar nieuw. Gebruik het

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

Antwoord 14

Tekenreeksen met datums zijn vergelijkbaar in JavaScript (als ze syntactisch hetzelfde zijn), bijvoorbeeld:

'2020-12-01' < '2020-12-02' == true

Dit betekent dat u deze uitdrukking kunt gebruiken in een aangepaste sorteerfunctie:

var arr = [{id:1, date:'2020-12-01'}, {id:1, date:'2020-12-15'}, {id:1, date:'2020-12-12'}]
function sortByDate(a, b) {
    if (a.date < b.date) {
        return 1;
    }
    if (a.date > b.date) {
        return -1;
    }
    return 0;
}
const sorted = arr.sort(sortByDate);
console.log(sorted);

Antwoord 15

Voor iedereen die wil sorteren op datum (VK-formaat), heb ik het volgende gebruikt:

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

Antwoord 16

Ik heb zojuist de Schwartziaanse transformatiehierboven weergegeven en als functie gemaakt. Er is een array, de sorteerfunctie functionen een boolean nodig als invoer:

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

Antwoord 17

["12 Jan 2018" , "1 Dec 2018", "04 May 2018"].sort(function(a,b) {
    return new Date(a).getTime() - new Date(b).getTime()
})

Antwoord 18

Als je net als ik een array hebt met datums die zijn opgemaakt als YYYY[-MM[-DD]]waar je specifiekere datums wilt bestellen vóór minder specifieke, heb ik dit bedacht handige functie:

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

Antwoord 19

arr is een array van objecten en elk object heeft date_prop wat een datum is. Je kunt het als volgt sorteren

arr = arr.sort(function (a, b) {
      var dateA = new Date(a.date_prop).getTime();
      var dateB = new Date(b.date_prop).getTime();
      return dateA < dateB ? 1 : -1;
    });

Antwoord 20

Bedankt voor die briljante antwoorden bovenaan. Ik heb een ietwat ingewikkeld antwoord bedacht. Alleen voor degenen die verschillende antwoorden willen vergelijken.

const data = [
    '2-2018', '1-2018',
    '3-2018', '4-2018',
    '1-2019', '2-2019',
    '3-2019', '4-2019',
    '1-2020', '3-2020',
    '4-2020', '1-2021'
]
let eachYearUniqueMonth = data.reduce((acc, elem) => {
    const uniqueDate = Number(elem.match(/(\d+)\-(\d+)/)[1])
    const uniqueYear = Number(elem.match(/(\d+)\-(\d+)/)[2])
    if (acc[uniqueYear] === undefined) {
        acc[uniqueYear] = []        
    } else{    
       if (acc[uniqueYear]  && !acc[uniqueYear].includes(uniqueDate)) {
          acc[uniqueYear].push(uniqueDate)
      }
    }
    return acc;
}, {})
let group = Object.keys(eachYearUniqueMonth).reduce((acc,uniqueYear)=>{
    eachYearUniqueMonth[uniqueYear].forEach(uniqueMonth=>{
    acc.push(`${uniqueYear}-${uniqueMonth}`)
  })
  return acc;
},[])
console.log(group);   //["2018-1", "2018-3", "2018-4", "2019-2", "2019-3", "2019-4", "2020-3", "2020-4"]

Other episodes