Удаление повторяющихся дат в двух массивах с помощью lodash / fp - PullRequest
0 голосов
/ 07 мая 2018

Я пытаюсь использовать более функциональный подход к отображению данных и не могу удалить дубликаты элементов из массива. То, чего я пытаюсь добиться, - это удаление и / или объединение элементов с одинаковой датой.

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

new Date(2018, 4, 7) === new Date(2018, 4, 7) //false new Date(2018, 4, 7) == new Date(2018, 4, 7) //false

Есть ли способ DeepMatch с использованием uniqBy или другой метод слияния или удаления дубликатов в функциональном подходе.

примечание: объекты / функции были упрощены до задачи.

const items = [{date: new Date(2018, 4, 7), wellbeing: 50}];
const days = [{date: new Date(2018, 4, 7)}, {date: new Date(2018, 4, 8)}];
const Row = (item) => item; // not real map just mock

function mapToRow(data) {
   return _.pipe([
    sortByDate,
    _.uniqBy('date'),
    _.map(Row)
  ])(data)
}
function sortByDate(array) {
  return array.sort((a, b) => {
    a = new Date(a.date);
    b = new Date(b.date);
    return a < b ? -1 : a > b ? 1 : 0;
  });
}

console.log(mapToRow(days.concat(items)));
<script src="https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js"></script>

может использовать lib, например момент

// ожидаемый результат

[{date: new Date(2018, 4, 7), wellbeing: 50}, {date: new Date(2018, 4, 8)}]

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Вы можете группировать по дате, а затем использовать карту с Object.assign для объединения:

const items = [{date: new Date(2018, 4, 7), wellbeing: 50}];
const days = [{date: new Date(2018, 4, 7)}, {date: new Date(2018, 4, 8)}];
const Row = (item) => item; // not real map just mock

function mapToRow(data) {
   return _.pipe([
    sortByDate,
    _.groupBy('date'),
    _.map(xs => Object.assign({}, ...xs)),
    _.map(Row)
  ])(data)
}
function sortByDate(array) {
  return array.sort((a, b) => {
    a = new Date(a.date);
    b = new Date(b.date);
    return a < b ? -1 : a > b ? 1 : 0;
  });
}

console.log(mapToRow(days.concat(items)));
<script src="https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js"></script>
0 голосов
/ 07 мая 2018

Вы можете использовать _.unionWith() и проверить равенство с помощью _.isEqual():

const items = [{date: new Date(2018, 4, 7), wellbeing: 50}];
const days = [{date: new Date(2018, 4, 7)}, {date: new Date(2018, 4, 8)}];

const result = _.unionWith(
  (arrVal, othVal) => _.isEqual(arrVal.date, othVal.date),
  items,
  days
);

console.log(result);
<script src="https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js"></script>

Только с ES6 вы можете уменьшить обоих массивов до Map , а затем распространить Map.values() обратно в массив :

const items = [{date: new Date(2018, 4, 7), wellbeing: 50}];
const days = [{date: new Date(2018, 4, 7)}, {date: new Date(2018, 4, 8)}];

const result = [...items.concat(days)
  .reduce((r, o) => {
    const time = o.date.getTime();
    return r.set(time, { ...r.get(time), ...o });
  }, new Map())
  .values()];
  
console.log(result);
...