Milan
Milan

Reputation: 25

Compare two object arrays and get the difference in Javascript

I have two arrays of objects:

\\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"}
]

I would like to have a result where are available offers, that means only the offers without already reserved desks.

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

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

I already tried solutions on the link above but without success, I just got a result array as sum of all objects from the two arrays.

            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);

Upvotes: 1

Views: 135

Answers (3)

perellorodrigo
perellorodrigo

Reputation: 536

You can do in a single function, like:

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);

So, what is exactly happening...

  • offers.filter runs a check for each element in the offers array.
  • reservations.findIndex will try to find if there is already a reservation for that offer. It does by going into the reservations array and checking if there is the same unique ID and same date for the offer that is currently filtering.
  • If the result is equal to -1 it means that there is no reservation for that offer. Therefore it is available.

I've used the dates as string for the sake of simplicity, you can just alter to Date object. Hope it helps!

EDIT

I've added a small helper function for you to compare if the dates are from the same day. You can check this answer for a more detailed explanation: how to tell if two dates are in the same day?

Upvotes: 1

Rajneesh
Rajneesh

Reputation: 5308

You can simply filter it with some inside it.

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);

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386560

You could take a Set and filter the reservations.

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);

Upvotes: 1

Related Questions