Создание кумулятивных объектов с использованием JavaScript - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть один массив дат и один массив объектов.У каждого есть свойство даты.Мне нужно отсортировать объекты по дате.Таким образом, для каждой даты в массиве даты я хотел бы создать накопительный объект с каждым объектом, свойство которого предшествует дате в массиве даты.

Например, следующий массив дати массив объектов:

['2017-11-5', '2018-3-1', '2018-3-22']

[{name: 'Jes', date: '2017-11-2'}, {name: 'Jill', date: '2018-1-5'}, {name: 'Joe', date: '2018-2-25'}, {name: 'Jack', date: '2018-3-21'}]

Желаемый результат будет:

[{name: 'Jes', date: '2017-11-2'}]

[{name: 'Jes', date: '2017-11-2'}, {name: 'Jill', date: '2018-1-5'}, {name: 'Joe', date: '2018-2-25'}]

[{name: 'Jes', date: '2017-11-2'}, {name: 'Jill', date: '2018-1-5'}, {name: 'Joe', date: '2018-2-25'}, {name: 'Jack', date: '2018-3-21'}]

Я пытаюсь сделать это примерно с 500 датами и 30 000 объектов,

Вот текущий фрагмент кода, но у меня возникают проблемы с производительностью из-за количества объектов, которые я перебираю.

    _.each(dtArray,function(i:Date){
  let dt = new Date(i);
  let filtered = _.filter(data,function(row){
    let dtVal = new Date(row['date']);
    return dtVal<=dt;
  });

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Существует несколько способов улучшить алгоритм, сохраняя ассоциативные индексы в enter image description here:

  • Предварительно рассчитать объекты даты и рассчитать их только один раз для обоих peopleи dates
  • Сортировка dates в порядке возрастания
  • Повторное использование предварительно рассчитанных / предварительно отфильтрованных результатов, см. Динамическое программирование
  • Сохранитьdates и people индексы для сохранения исходного порядка
  • Поменяйте местами элементы от remaining до lastChunk, чтобы уменьшить remaining размер, если people[i].date < dates[j]

Алгоритмкод:

function filter(dates, people){
    let lastChunk = [];
    let remaining = people;
    let results = [];
    // precalculate dates, preserve indexes and sort by date
    let sortedDates = dates
        .map((value, index) => {
            return {
                date: new Date(value),
                index: index
            };
        })
        .sort((a, b) => {
            return a.date<b.date?-1:a.date==b.date?0:1;
        });
    let peopleWithDates = people.map((value, index) => {
        value.dateObject = new Date(value.date);
        value.index = index;
        return value;
    });
    for(const i in sortedDates){
        const comp = sortedDates[i].date
        remaining = remaining.filter((value, index) => {
            if(value.dateObject<=comp){
                let itemIndex = value.index;
                delete value.dateObject;
                delete value.index;
                lastChunk.splice(itemIndex, 0, value);
                return false;
            }else{
                return true;
            }
        });
        results[sortedDates[i].index] = [...lastChunk];
    }
    return results;
}
0 голосов
/ 11 декабря 2018

Вы можете map() по датам, так как вам нужен один массив результатов для каждой даты.Затем на карте вы можете filter() людей на основе даты, чтобы создать этот массив:

let dates = ['2017-11-5', '2018-3-1', '2018-3-22']

let people = [{name: 'Jes', date: '2017-11-2'}, {name: 'Jill', date: '2018-1-5'}, {name: 'Joe', date: '2018-2-25'}, {name: 'Jack', date: '2018-3-21'}]

let cumul = dates.map(d => people.filter(person => person.date <= d))
console.log(JSON.stringify(cumul, null, 2))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...