Cách sắp xếp một mảng theo thuộc tính ngày


698

Nói rằng tôi có một mảng của một vài đối tượng:

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

Làm cách nào tôi có thể sắp xếp mảng này theo thành phần ngày theo thứ tự từ ngày gần nhất với ngày và giờ hiện tại? Hãy nhớ rằng mảng có thể có nhiều đối tượng, nhưng để đơn giản, tôi đã sử dụng 2.

Tôi sẽ sử dụng chức năng sắp xếp và một bộ so sánh tùy chỉnh?

CẬP NHẬT:

Trong trường hợp cụ thể của tôi, tôi muốn các ngày được sắp xếp từ gần đây nhất đến cũ nhất. Cuối cùng, tôi phải đảo ngược logic của hàm đơn giản như sau:

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

Điều này sắp xếp các ngày từ gần đây nhất.


Nếu bạn sử dụng hàm tạo ngày, hãy kiểm tra stackoverflow.com/questions/5619202/ cấp này
ohkts11

cách nhanh nhất là sử dụng mô đun mảng sắp xếp đẳng cấu , hoạt động tự nhiên trong cả trình duyệt và nút, hỗ trợ mọi loại đầu vào, trường được tính toán và thứ tự sắp xếp tùy chỉnh.
Lloyd

Câu trả lời:


1402

Câu trả lời đơn giản nhất

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

Câu trả lời chung chung hơn

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

Hoặc chặt chẽ hơn:

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

Câu trả lời chung chung, mạnh mẽ

Xác định hàm không đếm được tùy chỉnh sortBybằng cách sử dụng biến đổi Schwartzian trên tất cả các mảng:

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

Sử dụng nó như vậy:

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

Nếu ngày của bạn không thể so sánh trực tiếp, hãy tạo một ngày tương đương với ngày đó, vd

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

Bạn cũng có thể sử dụng điều này để sắp xếp theo nhiều tiêu chí nếu bạn trả về một mảng các giá trị:

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

Xem http://phrogz.net/JS/Array.prototype.sortBy.js để biết thêm chi tiết.


2
Tại sao không có return b-a;trong câu trả lời đơn giản?
corbacho

19
Không khuyên bạn nên tạo các đối tượng Date mới bên trong phương thức sắp xếp. Đã đánh các vấn đề hiệu suất sản xuất đặc biệt cho lý do đó. Không phân bổ bộ nhớ (và GC) trong một phương thức sắp xếp.
MikeMurko

4
cú pháp ví dụ đầu tiên gây ra lỗi trên angular7: Phía bên trái của một phép toán số học phải là loại 'bất kỳ', 'số', 'bigint' hoặc một loại enum
SURENDRANATH SONAWane

1
@MikeMurko bạn đã làm gì để khắc phục nó?
Sireini

@SURENDRANATHSONAWane chuyển đổi Ngày thành Dấu thời gian Unix: trả về Ngày mới (b.date) .getTime () - Ngày mới (a.date) .getTime ();
Robert Ostrowicki

147

Câu trả lời @Phrogz đều tuyệt vời, nhưng đây là một câu trả lời tuyệt vời, ngắn gọn hơn:

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

Sử dụng cách chức năng mũi tên

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

tìm thấy ở đây: Sắp xếp ngày trong Javascript


15
Làm toán trực tiếp a - bcũng sẽ làm việc. Vì vậy, array.sort((a, b) => a - b)(es6)
yckart

Đây là một giải pháp tốt khi sử dụng Typecript.
maartenpaauw

72

Sau khi sửa JSON, nó sẽ hoạt động với bạn ngay bây giờ:

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

45

Dữ liệu của bạn cần một số chỉnh sửa:

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

Sau khi sửa dữ liệu, bạn có thể sử dụng đoạn mã này:

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


Đối với bất kỳ ai sử dụng Bản mô tả, tôi có thể sắp xếp theo ngày bằng cách sử dụng chức năng này, trong khi những người khác sử dụng phép trừ ngày không thành công.
Danchat

24

Tôi khuyên dùng GitHub: Array sortBy - một sortByphương thức triển khai tốt nhất sử dụng biến đổi Schwartzian

Nhưng bây giờ chúng ta sẽ thử phương pháp này Gist: sortBy-old.js .
Hãy tạo một phương thức để sắp xếp các mảng có khả năng sắp xếp các đối tượng theo một số thuộc tính.

Tạo chức năng sắp xếp

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

}());

Đặt dữ liệu chưa sắp xếp

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

Sử dụng nó

Cuối cùng, chúng tôi sắp xếp các mảng, theo thuộc "date"tính nhưstring

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

Nếu bạn muốn bỏ qua trường hợp chữ cái, hãy đặt "parser"lại cuộc gọi:

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

Nếu bạn muốn coi trường "ngày" là Dateloại:

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

Tại đây bạn có thể chơi với ví dụ trên:
jsbin.com/lesebi


1
IE11 có vấn đề với dòng: if (toString.call (cfg)! == "[object Object]") cfg = {}; Nếu bạn thay thế nó bằng if (Object.prototype.toString.call (cfg)! == "[Object Object]") cfg = {}; bạn cũng sẽ ổn với IE11.
skribbz14

1
Giải pháp tuyệt vời
Moses Machua

14

Điều này sẽ làm khi ngày của bạn ở định dạng này (dd / mm / yyyy).

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

    return arr;
  }

Sau đó gọi sortByDate(myArr);


12

Bạn có thể sử dụng sortBy trong js gạch dưới.

http://underscorejs.org/#sortBy

Mẫu vật:

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

Cách hoàn hảo và ngắn nhất để làm điều đó!
Bhasta Kalariya

8

Tôi sẽ thêm điều này vào đây, vì một số cách sử dụng có thể không thể tìm ra cách đảo ngược phương pháp sắp xếp này.

Để sắp xếp theo 'sắp tới', chúng ta chỉ cần trao đổi a & b, như vậy:

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

Lưu ý rằng abây giờ là ở phía bên tay trái, và bở bên phải ,: D!


7

Cá nhân tôi sử dụng cách tiếp cận sau đây để sắp xếp ngày.

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

6

tôi đã có thể đạt được sắp xếp bằng cách sử dụng các dòng dưới đây:

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

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

2

Đối với bất kỳ ai muốn sắp xếp theo ngày (định dạng của Vương quốc Anh), tôi đã sử dụng như sau:

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

2

Tôi vừa thực hiện biến đổi Schwartzian được mô tả ở trên và được thực hiện như chức năng. Phải mất một array, sắp xếp functionvà boolean làm đầu vào:

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


2

Cảm ơn Ganesh Sanap. sắp xếp các mục theo trường ngày từ cũ đến mới. Sử dụng nó

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

1
Lý do trừ là gì?
Янов Алексей

2

Nếu giống như tôi, bạn có một mảng với các ngày được định dạng như YYYY[-MM[-DD]]nơi bạn muốn đặt hàng ngày cụ thể hơn trước những ngày ít cụ thể hơn, tôi đã đưa ra chức năng tiện dụng này:

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

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

Vui lòng giải thích ngắn gọn câu trả lời của bạn và kiểm tra định dạng mã của bạn.
dthulke

Sẽ thất bại cho ngày cũ.
Oliver Dixon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.