2016-12-11 4 views
6

Я искал этот вопрос, и никакой существующий ответ не применяется. Рассмотрим следующий пример:Как отсортировать массив объектов, где указаны даты

[ 
    { 'August 17th 2016': [75] }, // 75 is the length of the array which contains up to 75 objects ... 
    { 'August 1st 2016': [5] }, 
    { 'August 28th 2016': [5] }, 
    ... 
] 

Что является лучшим способом для сортировки объектов в этом массиве по дате и по-прежнему держать «английский» представление их ключа?

Примечание: Ключ используется как ярлык диаграммы.

Везде, где я смотрю array.sort, используется, но это на ключ от объекта created_at.

Результат должен быть:

[ 
    { 'August 1st 2016': [5] }, 
    { 'August 17th 2016': [75] } 
    { 'August 28th 2016': [5] }, 
    ... 
] 

Я не уверен, как поступить, так что я не имею ничего, чтобы показать .

+0

Возможно, дубликат? http://stackoverflow.com/questions/979256/sorting-an-array-of-javascript-objects – tbg

+0

Возможная дубликация [Сортировка вложенных массивов объектов по дате] (http://stackoverflow.com/questions/9293290/sorting -nested-arrays-of-objects-by-date) – Shaffanhoon

+2

Ни один из них не является правильным дубликатом, учитывая, что он хочет сортировать по ключу. –

ответ

6

Это можно сделать, используя date.parse на объекте. Я взял первый ключ объекта, поскольку, по-видимому, в каждой записи массива только 1. Сложная часть состоит в том, что date.parse не работает на «12-й» или «1-й», поэтому нам нужно временно заменить «th» или «st» на ,. Таким образом, date.parse работает над строкой.

var dates = [{ 
 
    'August 17th 2016': [75] 
 
}, { 
 
    'August 1st 2016': [5] 
 
}, { 
 
    'August 28th 2016': [5] 
 
}] 
 

 
const replaceOrdinals = o => { 
 
    return Object.keys(o)[0].replace(/\w{2}(\d+$)/, ',$1'); 
 
} 
 

 
dates = dates.sort((a, b) => { 
 
    return Date.parse(replaceOrdinals(a)) - Date.parse(replaceOrdinals(b)) 
 
}); 
 

 
console.log(dates);

Имейте в виду:

От @adeneo в комментариях: Date.parse это implentation зависит. Возможно, вам захочется прочитать документацию, чтобы определить, будут ли вещи, подобные часовым поясам, испортить вещи. В качестве более надежного метода вы можете использовать что-то вроде moment.js для синтаксического анализа даты.

+1

Следует отметить, что 'Date.parse' зависит от реализации и не обязательно будет работать над этими строками даты вообще в некоторой реализации. – adeneo

+0

Можете ли вы это объяснить: 'replaceOrdinals = o =>' Что мы здесь делаем? @KevBot – TheWebs

+0

@TheWebs, это ['функция стрелок'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions). Версия ES5 была бы следующей: 'var replaceOrdinals = function (o) {...}'. Если в этом случае мне нужен только один аргумент, поэтому '()' не нужны вокруг 'o'. '=>' Является лишь частью синтаксиса, хотя он делает несколько разных вещей в зависимости от того, используете ли вы фигурные скобки сразу после него. Эти вещи объясняются в этой ссылке. Отвечает ли это на ваш вопрос? – KevBot

0

Решение в answer by Kevbot является элегантным, но его применение ограничено браузерами ES6 с реализацией date.parse(), который соответствует определенному формату даты, используемому OP.

Вместо добавления библиотеки, такие как moment.js только чтобы избежать date.parse() зависимость, индивидуальное решение, которое будет работать в любой среде JavaScript (в том числе старые браузеры) могут быть сделаны с помощью нескольких строк кода:

var dates = [ 
 
    {'August 17th 2016': [75]}, 
 
    {'August 1st 2016': [5]}, 
 
    {'August 28th 2016': [5]} 
 
]; 
 

 
dates.sort(function(a, b){ 
 
    var i, j; 
 
    for(i in a); //get datestring a 
 
    for(j in b); //get datestring b; 
 
    return MMMDDYYYYtoSortableNumber(i) - 
 
    MMMDDYYYYtoSortableNumber(j); 
 
}); 
 

 
console.log(dates); 
 

 
// MMMDDYYYYtoSortableNumber() converts datestrings 
 
// such as "April 5th 1969" to 19690405. 
 
// Month name to digit approach adapted from 
 
// https://gist.github.com/atk/1053863 
 
    
 
function MMMDDYYYYtoSortableNumber(datestring) { 
 
    var mdy = datestring.match(/\w(\w\w)\D+(\d+)\D+(\d+)/); 
 
    return mdy[3] * 10000 + 
 
    ' anebarprayunulugepctovec'.search(mdy[1]) * 50 + 
 
    mdy[2] * 1; 
 
}

Пожалуйста, обратите внимание, что это может быть безопаснее представлять datestrings в качестве значений объекта, а не ключи объекта. Затем они будут легче извлекаться безопасно (и быстрее для доступа). Например.

{label: 'August 17th 2016', data: [75]},