I'm trying to take a more functional approach to displaying data and having trouble removing duplicate items from an array. What I'm trying to achieve is removing and/or merge items which are of the same date.
I've tried using the _.uniqBy
but it just returns the list untouched it's because it's a date object and therefore.
new Date(2018, 4, 7) === new Date(2018, 4, 7)
//false
new Date(2018, 4, 7) == new Date(2018, 4, 7)
//false
is there a way to deepMatch using uniqBy
or another method of merging or removing duplicates in a functional approach.
note: objects/functions have been simplified to the problem.
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>
can use lib such as moment
// expected outcome
[{date: new Date(2018, 4, 7), wellbeing: 50}, {date: new Date(2018, 4, 8)}]
You can use _.unionWith()
, and check for equality using _.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>
With just ES6, you can reduce both arrays to a Map, and then spread the Map.values()
back to array:
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);