使用lodash / fp删除两个数组中的重复日期

时间:2018-05-07 20:48:53

标签: javascript ecmascript-6 lodash

我正在尝试采用更实用的方法来显示数据,并且无法从阵列中删除重复的项目。我想要实现的是删除和/或合并具有相同日期的项目。

我已尝试使用_.uniqBy,但它只是返回未触及的列表,因为它是一个日期对象,因此。

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

有没有办法使用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 :(得分:2)

您可以使用_.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,您可以reduce将两个数组都Map,然后spread 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);

答案 1 :(得分:1)

您可以按日期分组,然后使用带有Object.assign的地图进行合并:

&#13;
&#13;
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)));
&#13;
<script src="https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js"></script>
&#13;
&#13;
&#13;