比较两个对象数组并获取 Javascript 中的差异

Posted

技术标签:

【中文标题】比较两个对象数组并获取 Javascript 中的差异【英文标题】:Compare two object arrays and get the difference in Javascript 【发布时间】:2020-09-18 19:51:20 【问题描述】:

我有两个对象数组:

\\offers
[
DeskUID: "B11A13", Day: 06 Jun 2020
DeskUID: "B11A13", Day: 07 Jun 2020
DeskUID: "B12B34", Day: 23 Jun 2020
]

\\reservations
[
DeskUID: "B11A13", Day: 06 Jun 2020, Name: "Mike"
DeskUID: "B12B34", Day: 23 Jun 2020, Name: "Ali"
]

我想得到一个结果,那里有可用的报价,这意味着只有没有已经预订座位的报价。

\\result
[
DeskUID: "B11A13", Day: 07 Jun 2020
]

How to get the difference between two arrays of objects in javascript

我已经在上面的链接上尝试了解决方案,但没有成功,我只是得到了一个结果数组作为两个数组中所有对象的总和。

            function comparer(otherArray)
                return function(current)
                var reserveDay = new Date (current.Day)
                    return otherArray.filter(function(other)
                        var offerDay = new Date (other.Day)
                        return other.DeskUID == current.DeskUID && offerDay == reserveDay
                    ).length == 0;
                
            

            var onlyInA = offers.filter(comparer(reservations));
            var onlyInB = reservations.filter(comparer(offers));

            result = onlyInA.concat(onlyInB);

【问题讨论】:

你的两个 Date 对象永远不会相等,因为它们是不同的对象引用,即使输入值相同 您可以使用 lodash 的 isEqual 进行深度对象比较:lodash.com/docs/4.17.15#isEqual 【参考方案1】:

你可以在一个函数中做,比如:

const available = offers.filter(offer =>  
  return reservations.findIndex(reservation => reservation.DeskUID === offer.DeskUID && sameDay(new Date(reservation.Day), new Date(offer.Day))) === -1;
);

function sameDay(d1, d2) 
  return (
    d1.getFullYear() === d2.getFullYear() &&
    d1.getMonth() === d2.getMonth() &&
    d1.getDate() === d2.getDate()
  );


console.log(available);

那么,到底发生了什么……

offers.filter 对 offer 数组中的每个元素进行检查。 reservations.findIndex 将尝试查找该优惠是否已有预订。它通过进入预订数组并检查当前正在过滤的报价是否存在相同的唯一 ID 和相同的日期来实现。 如果结果等于 -1,则表示该报价没有保留。因此它是可用的。

为了简单起见,我将日期用作字符串,您可以更改为 Date 对象。希望对您有所帮助!

编辑

我添加了一个小帮助函数,供您比较日期是否来自同一天。您可以查看此答案以获得更详细的说明:how to tell if two dates are in the same day?

【讨论】:

感谢您的反馈。我的数组中的天数是“日期”数据类型。我该如何调整您的解决方案? ``` const 可用 = 便利优惠.filter(offer => return reservedDesks.findIndex(reservation => reservation.DeskUID === offer.DeskUID && (new Date (reservation.Day)) !== (new Date (offer.天))) !== -1; ); console.log(可用); ``` 我已经编辑了答案以显示如何比较日期。您可以使用(new Date (reservation.Day)) !== (new Date (offer.Day)),因为每个日期都是 Date 对象的不同实例。因此它们永远不会相同(即使日期相同)。我还修复了代码中的一些逻辑错误 我发现这个解决方案在 IE11 中不起作用。是否可以使用其他适合 IE11 的方法? IE 控制台显示“语法错误”。我认为这是由于箭头功能。 很有可能。您可以替换为通常的功能,它会以相同的方式工作【参考方案2】:

您可以使用Set 并过滤预订。

var getKey = ( DeskUID, Day ) => [DeskUID, Day].join('|'),
    offers = [ DeskUID: "B11A13", Day: "2020-06-06" ,  DeskUID: "B11A13", Day: "2020-06-07" ,  DeskUID: "B12B34", Day: "2020-06-23" ],
    reservations = [ DeskUID: "B11A13", Day: "2020-06-06", Name: "Mike" ,  DeskUID: "B12B34", Day: "2020-06-23", Name: "Ali" ],
    reservationsSet = new Set(reservations.map(getKey)),
    open = offers.filter(o => !reservationsSet.has(getKey(o)));

console.log(open);

【讨论】:

【参考方案3】:

你可以简单地在filter里面加上some

var offers = [ DeskUID: "B11A13", Day: "2020-06-06" ,  DeskUID: "B11A13", Day: "2020-06-07" ,  DeskUID: "B12B34", Day: "2020-06-23" ];
var reservations = [ DeskUID: "B11A13", Day: "2020-06-06", Name: "Mike" ,  DeskUID: "B12B34", Day: "2020-06-23", Name: "Ali" ];

var result = offers.filter(k=>!reservations.some(d=>d.DeskUID == k.DeskUID && d.Day==k.Day));

console.log(result);

【讨论】:

以上是关于比较两个对象数组并获取 Javascript 中的差异的主要内容,如果未能解决你的问题,请参考以下文章

Javascript中比较两个无序对象数组的自定义实现

Lodash / javascript:比较两个集合并返回差异[重复]

如何根据javascript中的键合并和替换两个数组中的对象?

比较两个对象数组,并将匹配值的元素排除到JS中的新数组中

比较并将正确的值推送到 JavaScript/TypeScript 中的对象数组

JavaScript如何比较两个数组的内容是否相同