Сортировать массив с датой в виде строки по предстоящим датам - PullRequest
0 голосов
/ 23 января 2019

Поэтому я пытаюсь отсортировать массив так, чтобы первый элемент был таким же, как текущий день и месяц или ближайшая запись.

Мой массив выглядит так:

[
    [
       "Firstname Lastname",
        "1979-01-03",
        "40"
    ],
    [
        "Firstname Lastname",
        "1996-01-23",
        "23"
    ],
    [
        "Firstname Lastname",
        "1977-01-28",
        "41"
    ],
    [
        "Firstname Lastname",
        "1983-03-11",
        "35"
    ],
    [
       "Firstname Lastname",
       "1977-03-30",
        "41"
    ],
    [
       "Firstname Lastname",
        "1975-05-08",
        "43"
    ]
]

Я выяснил, как отсортировать массив по дню месяца, но затем он игнорирует сам месяц

relativeYearDay(date) {
    let differenceDay = new Date(date).getDate() - new Date().getDate();

     if (differenceDay < 0) {
         differenceDay += 365;
     }

     return differenceDay;
}

getUpcomingBirthdays() {
     return this.birthdays.slice(0).sort((a, b) => {
         return this.relativeYearDay(a[1]) - this.relativeYearDay(b[1]);
    });
},

Как я уже говорил, это возвращает отсортированный массив, основанный на дне месяца.

Как бы я сделал это для дня и месяца?

Ответы [ 4 ]

0 голосов
/ 23 января 2019

Вы можете отсортировать массив с помощью алгоритма сортировки с разделами, где вы берете дату в качестве разделителя, перемещаете меньшие значения в конец массива и сортируете все остальные по дате.

В этом подходе используется строка части, поскольку ISO 8601 даты сортируются по строке.

var array = [["Firstname Lastname", "1979-01-03", "40"], ["Firstname Lastname", "1996-01-23", "23"], ["Firstname Lastname", "1977-01-28", "41"], ["Firstname Lastname", "1983-03-11", "35"], [ "Firstname Lastname","1977-03-30", "41"], [ "Firstname Lastname", "1975-05-08", "43"]],
    day = (new Date).toISOString().slice(5, 10)

array.sort(({ 1: a }, { 1: b }) =>
    (a.slice(5) < day) - (b.slice(5) < day) || a.slice(5).localeCompare(b.slice(5)));

console.log(array.map(a => a.join(' | ')));
0 голосов
/ 23 января 2019

Ваш первоначальный ответ был очень близок.При сортировке вам просто необходимо выяснить дату предстоящего дня рождения пользователя.

const birthdays = [
    [ "Firstname Lastname", "1979-01-03", "40" ],
    [ "Firstname Lastname", "1996-01-23", "23" ],
    [ "Firstname Lastname", "1977-01-28", "41" ],
    [ "Firstname Lastname", "1983-03-11", "35" ],
    [ "Firstname Lastname", "1977-03-30", "41" ],
    [ "Firstname Lastname", "1975-05-08", "43" ]
];


function getNextBirthday(date) {
    // Current Date
    let currentDate = new Date();

    // Set the users birthday to this year (originally from thier birth year)
    let birthday = new Date(date);
    birthday.setFullYear(currentDate.getFullYear());

    // If the birthday has already occured this year.  Then thier next birthday is next year.
    if (birthday - currentDate < 0) {
        birthday.setFullYear(currentDate.getFullYear() + 1);
    }

    // Return the users next birthday as a date.
    return birthday;
}

function getUpcomingBirthdays() {
     return birthdays.slice(0).sort((a, b) => {
         return getNextBirthday(a[1]) - getNextBirthday(b[1]);
    });
}

Редактировать: Добавлены комментарии и исправлена ​​небольшая ошибка в коде.

0 голосов
/ 23 января 2019

На самом деле, поскольку вы хотите отсортировать по следующим дням рождения, вы можете установить для текущего года все значения dates при сравнении с current date. Если разница между ними отрицательна (т. Е. День рождения уже наступил), вы можете добавить смещение на 1 год.

const birthdays = [
    ["Firstname Lastname", "1979-01-03", "40"],
    ["Firstname Lastname", "1996-01-23", "23"],
    ["Firstname Lastname", "1977-01-28", "41"],
    ["Firstname Lastname", "1983-03-11", "35"],
    ["Firstname Lastname", "1977-03-30", "41"],
    ["Firstname Lastname", "1975-05-08", "43"]
];

function distanceToBirthday(date)
{
    let currDate = new Date();
    currDate.setHours(0, 0, 0, 0);
    let currYear = currDate.getFullYear();

    let offset = new Date();
    offset.setHours(0, 0, 0, 0);
    offset.setFullYear(currYear + 1);

    date = new Date(date + " 00:00");
    date.setFullYear(currYear);

    let diff = date - currDate;
    return (diff < 0) ? diff + offset.getTime() : diff;
}

function getUpcomingBirthdays(bdays)
{
    return bdays.slice(0).sort(
        (a, b) => distanceToBirthday(a[1]) - distanceToBirthday(b[1])
    );
}

console.log(getUpcomingBirthdays(birthdays));
0 голосов
/ 23 января 2019

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

В простом кодировании ... и может дать вам несколько идей, чтобы превратить его в процедуру сортировки

const data = [
    [
       "Firstname Lastname",
        "1979-01-03",
        "40"
    ],
    [
        "Firstname Lastname",
        "1996-01-23",
        "23"
    ],
    [
        "Firstname Lastname",
        "1977-01-28",
        "41"
    ],
    [
        "Firstname Lastname",
        "1983-03-11",
        "35"
    ],
    [
       "Firstname Lastname",
       "1977-03-30",
        "41"
    ],
    [
       "Firstname Lastname",
        "1975-05-08",
        "43"
    ]
];
const now = new Date().getTime();
let nearestIndex = -1;
let nearest = 0;

data.forEach( (item, index) => {
  if(nearest ==0 || now-new Date(item[1]).getTime() < nearest) {
    nearest = now-new Date(item[1]).getTime();
    nearestIndex = index;
  }  
});

console.log(`Nearest date is at index ${nearestIndex}`, data[nearestIndex], nearest, nearestIndex);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...