Ngày tối thiểu / Tối đa trong một mảng?


106

Làm cách nào tôi có thể tìm ra ngày tối thiểu và ngày tối đa từ một mảng ngày tháng? Hiện tại, tôi đang tạo một mảng như sau:

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

Có một chức năng tích hợp để thực hiện việc này hay tôi phải tự viết?

Câu trả lời:


137

Mã được kiểm tra với IE, FF, Chrome và hoạt động bình thường:

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

1
Chuyển đổi số không được áp dụng cho chuỗi '2011/06/25' mà cho Ngày mới ('2011/06/25'). Số (Ngày mới ('2011/06/25')) === 1308949200000. Mã được kiểm tra trong Chrome, IE, FF
Andrew D.

@RobG - "Chuỗi ngày" có nghĩa là gì?
Andrew D.

vd dates.push('2011/06/05'). Sử dụng chuỗi, mảng có thể được sắp xếp đơn giản và các giá trị thành viên đầu tiên và cuối cùng được trả về và chuyển đổi thành ngày tháng nếu cần thiết.
RobG

10
@RobG - trong câu hỏi ở trên mảng chứa các đối tượng Ngày, không phải "chuỗi ngày" - cũng phản hồi cho các đối tượng Ngày. Sử dụng "chuỗi ngày" là một thực tế rất tệ trong một số trường hợp. So sánh hai chuỗi ngày tiếp theo: "2011/06/05" và "2011/06/05 00:00:00". 1) dưới dạng chuỗi: ("2011/06/05" === "2011/06/05 00:00:00"): kết quả là sai; 2) như các đối tượng Ngày (có chuyển đổi thành số): Số (Ngày mới ("2011/06/05")) === Số (Ngày mới ("2011/06/05 00:00:00")): kết quả là đúng - là một kết quả đúng!
Andrew D.

@AndrewD. Nếu các chuỗi ngày nhất quán, chẳng hạn YYYY/MM/DD HH:MM:SSvà có rất nhiều chuỗi liên quan, bạn có khuyên bạn nên so sánh chuỗi hoặc Number(new Date(dateString))so sánh không?
BlackPanther

83

Cái gì đó như:

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

Đã thử nghiệm trên Chrome 15.0.854.0 dev


Array.reduce()không có sẵn trong IE trước IE9. Ý tưởng tuyệt vời.
jfriend00

1
Array.reduce () có thể được triển khai với hàm tương đương javascript
Andrew D.

Chính xác, hãy đọc về nó trong 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 có thể chết, và thực sự, nó hiện chỉ chiếm 9,3% lượng sử dụng trình duyệt toàn cầu tính đến tháng 4 năm 2013.
wprl

3
Giải pháp rút gọn hoạt động cho chuỗi và cho các đối tượng Ngày.
Benoit

33

_.min_.maxlàm việc trên các mảng ngày tháng; sử dụng chúng nếu bạn đang sử dụng Lodash hoặc Underscore và cân nhắc sử dụng Lodash (cung cấp nhiều chức năng tiện ích như thế này) nếu bạn chưa sử dụng.

Ví dụ,

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

sẽ trả về ngày thứ hai trong mảng (vì là ngày sớm nhất).


3
Không trả lời trực tiếp câu hỏi của OP. OP đang hỏi liệu một phương thức tích hợp sẵn có trong JavaScript hay không. Vì vậy, mặc dù _.min & _.max có thể được sử dụng để tìm ngày tối thiểu hoặc tối đa, nhưng không phải là thứ OP đang tìm kiếm. Ngoài ra, việc xem xét một thư viện tiện ích là một chủ đề có nhiều ý kiến.
detj

13
Tôi tôn trọng không đồng ý và nghĩ rằng đây là một câu trả lời hữu ích, @detj - câu hỏi của OP như hiện tại được cho là có một chức năng tích hợp sẵn hoặc anh ta phải viết riêng, nhưng điều này không đúng. Đối với tôi, có vẻ hợp lý khi chỉ ra các thư viện tiện ích như một giải pháp thay thế cho một trong hai giải pháp được đề xuất của OP. Nhưng lý do của bạn là có thể bảo vệ được, và lá phiếu của bạn là của riêng bạn.
Mark Amery,

16

Tương tự như áp dụng, bây giờ với spread :

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

(có thể là một bình luận về câu trả lời hay nhất)


12

Vì ngày tháng được chuyển đổi thành kỷ nguyên UNIX (số), bạn có thể sử dụng Math.max / min để tìm những ngày đó:

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

(chỉ được thử nghiệm trong chrome, nhưng sẽ hoạt động trên hầu hết các trình duyệt)


8

** Sử dụng các nhà khai thác Spread | 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);

Điều đó sẽ cung cấp ngày tối thiểu từ mảng.

Viết tắt của nó Math.min.apply (null, ArrayOfdates);


1
Nếu bạn phản đối, vui lòng bình luận. Tại sao đây là một lựa chọn tồi? Tôi thích cú pháp và đối với các mảng nhỏ, hình phạt hiệu suất là không đáng kể.
GijsjanB

1
Tôi đã bị phản đối. Câu trả lời của Rudresh là một bản sao của tôi ở trên. Không hiểu tại sao mọi người không thích điều này. Đó là một dòng mã so với nhiều dòng.

3
Điều này trả về một số không phải là ngày tháng, do đó bạn phải chuyển đổi nó trở lại thành ngày tháng. Nhưng nó khá thanh lịch nếu không.
Tomáš Hübelbauer

6

ONELINER :

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

kết quả là các biến minmaxđộ phức tạp O (nlogn) , ví dụ có thể chỉnh sửa ở đây . Nếu mảng của bạn không có giá trị ngày tháng (như null), hãy xóa nó trước dates=dates.filter(d=> d instanceof Date);.


2
var max_date = dates.sort(function(d1, d2){
    return d2-d1;
})[0];

1

Các câu trả lời ở trên không xử lý các giá trị trống / không xác định để sửa lỗi này, tôi đã sử dụng mã dưới đây và thay thế các khoảng trống bằng 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));

Tôi đã thêm một bản demo javascript đơn giản ở đây và sử dụng nó làm bộ lọc với AngularJS trong codepen này


0

Đây là một cách đặc biệt tuyệt vời để làm điều này (bạn có thể nhận được tối đa một mảng đối tượng bằng cách sử dụng một trong các thuộc tính đối tượng): Math.max.apply(Math,array.map(function(o){return o.y;}))

Đây là câu trả lời được chấp nhận cho trang này: Tìm giá trị tối đa của một thuộc tính trong một mảng đối tượng


-2

Sử dụng Khoảnh khắc , Dấu gạch dướijQuery , để lặp lại một mảng ngày tháng.

JSON mẫu:

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

Hy vọng nó giúp.

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.