Каков элегантный способ получить последнюю дату из массива объектов на стороне клиента?
Я использую angularjs в проекте.
Я получаю массив объектов с сервера.
Каждый объект содержит несколько свойств, а один из них - свойство даты.
Вот массив (в json), который я получаю от сервера:
[
{
"Address": 25,
"AlertType": 1,
"Area": "North",
"MeasureDate": "2019-02-01T00:01:01.001Z",
"MeasureValue": -1
},
{
"Address": 26,
"AlertType": 1,
"Area": "West",
"MeasureDate": "2016-04-12T15:13:11.733Z",
"MeasureValue": -1
},
{
"Address": 25,
"AlertType": 1,
"Area": "North",
"MeasureDate": "2017-02-01T00:01:01.001Z",
"MeasureValue": -1
}
.
.
.
]
Мне нужно получить последнюю дату из массива.
Каков элегантный способ получить последнюю дату из массива объектов?
Ответы
Ответ 1
Чистый способ сделать это - преобразовать каждую дату в Date()
и взять максимум
new Date(Math.max.apply(null, a.map(function(e) {
return new Date(e.MeasureDate);
})));
где a
- массив объектов.
Это сопоставляет каждый объект в массиве с датой, созданной со значением MeasureDate
. Затем этот сопоставленный массив применяется к функции Math.max
для получения самой последней даты, а результат преобразуется в дату.
Сопоставляя строковые даты с объектами JS Date, вы в конечном итоге используете решение типа мин/макс дат в массиве?
-
Менее чистым решением было бы просто сопоставить объекты со значением MeasureDate
и отсортировать массив строк. Это работает только из-за определенного формата даты, который вы используете.
a.map(function(e) { return e.MeasureDate; }).sort().reverse()[0]
Если производительность имеет значение, вы можете использовать reduce
массив, чтобы получить максимум вместо использования sort
и reverse
.
Ответ 2
Если вы хотите получить весь объект, а не только дату...
Если для a
был назначен OP массив объектов, то вы получите объект с самой последней датой:
var mostRecentDate = new Date(Math.max.apply(null, a.map( e => {
return new Date(e.MeasureDate);
})));
var mostRecentObject = a.filter( e => {
var d = new Date( e.MeasureDate );
return d.getTime() == mostRecentDate.getTime();
})[0];
a.map
получает даты из массива объектов.
new Date
применяется к каждой дате, делая дату объектами
Math.max.apply
находит самый последний
- Мы нашли самую последнюю дату, теперь нам нужен объект.
a.filter
проходит через исходный массив a
.
- Нам нужен какой-то способ сравнения дат, поэтому мы используем
.getTime()
, который возвращает количество миллисекунд с 01.01.1970. Это будет учитывать как время, если оно определено, так и дату.
- Когда правильная дата найдена, возвращается
true
, и .filter
дает нам именно этот объект.
Примечание. Это решение является расширением ответа @archyqwerty выше. Их решение дало только самую последнюю дату из массива объектов, это решение дает вам весь объект, членом которого была дата.
Ответ 3
Модификация Антону Харальду Ответ: массив, в котором я использую ModDate вместо MeasureDate. Я выбираю самую последнюю дату. Это работает.
getLatestDate(xs) {
if (xs.length) {
return xs.reduce((m,v,i) => (v.ModDate > m.ModDate) && i ? v : m).ModDate;
}
}
m = аккумулятор, v = ток, я = индекс
Окружающая среда: TypeScript, ES6
Ответ 4
function getLatestDate(data) {
// convert to timestamp and sort
var sorted_ms = data.map(function(item) {
return new Date(item.MeasureDate).getTime()
}).sort();
// take latest
var latest_ms = sorted_ms[sorted_ms.length-1];
// convert to js date object
return new Date(latest_ms);
}
var data = [{MeasureDate: "2014-10-04T16:10:00"},
{MeasureDate: "2013-10-04T16:10:00"},
{MeasureDate: "2012-10-04T16:10:00"}];
getLatestDate(data).toString(); // "Sat Oct 04 2014 18:10:00 GMT+0200 (CEST)"
Эта функция возвращает последнюю дату в качестве объекта даты JavaScript. Вы также можете превратить его в ISO-String (формат исходных данных) с помощью метода Date-Object toISOString().
var date_str = "2012-10-04T16:10:00";
(new Date(date_str)).toISOString(); // "2012-10-04T16:10:00.000Z"
Как вы можете видеть, результат метода всегда включает нуль миллисекунды в конце. Если в результате вам понадобится исходная ISO-строка ISO, вы можете пойти со следующей функцией:
function getLatestDate2(data) {
var sorted = data.map(function(item) {
var MeasureDate = item.MeasureDate;
return {original_str: MeasureDate,
in_ms: (new Date(MeasureDate)).getTime()}
}).sort(function(item1, item2) {
return (item1.in_ms < item2.in_ms)
});
// take latest
var latest = sorted[0];
return latest.original_str;
}
getLatestDate2(data); // "2014-10-04T16:10:00"
Ответ 5
Вдохновленный многими предложениями и комментариями в этой теме, вот еще одно решение проблемы. Это очень быстро, поскольку отсутствует преобразование объекта даты.
function getLatestDate(xs) {
if (xs.length) {
return xs.reduce((m, i) => (i.MeasureDate > m) && i || m, "")
.MeasureDate;
}
}
Здесь версия для браузера, не поддерживающая функции стрелок:
function getLatestDateSave(xs) {
if (xs.length) {
return xs.reduce(function(m, i) {
return (i.MeasureDate > m) && i || m;
}, "").MeasureDate;
}
}
Ответ 6
В дополнение к ответу @Travis Heeter возвращается объект, содержащий самую последнюю дату:
array.reduce((a, b) => (a.MeasureDate > b.MeasureDate ? a : b));
Возможно, более надежное решение может заключаться в том, чтобы каждый раз преобразовывать строки в объекты Date
. Может быть заметно медленнее, если иметь дело с (очень) большими массивами:
array.reduce((a, b) => {
return new Date(a.MeasureDate) > new Date(b.MeasureDate) ? a : b;
}
Ответ 7
var dates = [];
dates.push(new Date("2019/06/25"));
dates.push(new Date("2019/06/26"));
dates.push(new Date("2019/06/27"));
dates.push(new Date("2019/06/28"));
function GFG_Fun() {
var maximumDate=new Date(Math.max.apply(null, dates));
var minimumDate=new Date(Math.min.apply(null, dates));
}