1

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);
2
  • Your two Date objects will never be equal since they are different object references even if the input values are the same Commented May 31, 2020 at 13:00
  • You can use lodash's isEqual for deep object comparisons: lodash.com/docs/4.17.15#isEqual Commented May 31, 2020 at 13:01

3 Answers 3

1

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?

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you, for your feedback. Days in my arrays are "Date" data type. How can I adjust your solution? ``` const available = convenientOffers.filter(offer => { return reservedDesks.findIndex(reservation => reservation.DeskUID === offer.DeskUID && (new Date (reservation.Day)) !== (new Date (offer.Day))) !== -1; }); console.log(available); ```
I've edited the answer to show how can you compare the dates. You can do (new Date (reservation.Day)) !== (new Date (offer.Day)) because each date is a different instance of the Date object. Therefore they will never be the same (even if the dates are the same). I've also fixed a little logic error in the code
I found out that this solution is not working in IE11. Is it possible to use some other method which is suitable for IE11?
IE console says "Syntax Error". I assume it is due to the arrow functions.
It is likely. You can just replace to the usual functions, it will work the same way
1

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

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.