0

I'm experiencing some weird behavior with a JavaScript function which I think may be a syntax issue/misunderstanding on my part as to how JavaScript "returns" function. The code in question looks like this:

   const preventOverlapInSchedule = (start, end) => {
    duties.forEach(function (duty) {
      if (
        (start >= duty.start && start <= duty.end) ||
        (end >= duty.start && end <= duty.end) ||
        (start <= duty.start && end >= duty.end)
      ) {
        console.log("false");
        return false;
      }
    });
    console.log("true");
    return true;
  };

This function is then used to prevent a scheduling conflict. However both the console log statements above are printing. Coming from Java, traditionally I would expect that the second the if condition evaluates to true, the function should return false, indicating that there is a scheduling conflict, i.e. the start time or end time of the new event has either partial or full overlap with another event already recorded, and then the function should immediately exit.

However the behavior I'm noticing is that regardless of the scheduling of the event, both of the console logs above print to the screen, which would indicate that returning false within my if statement does not cause the JavaScript function to exit immediately. Can anyone tell me why this is happening?

3
  • 3
    You're returning from the forEach callback so the outer function always returns true. Use a for (...) loop. Better yet, use return duties.some(e => /* predicate */). Lastly, the function breaks idempotency/scoping rules by not taking duties as a parameter. Commented Dec 17, 2020 at 0:30
  • 2
    Returning from a forEach does not return from the outer function. Commented Dec 17, 2020 at 0:31
  • Thanks y'all!! Standard for in loop works perfectly. Anonymous functions and callbacks are still new to me and still kill me sometimes. The duties parameter is actually a stateful variable within my React application so it's scoped correctly. Commented Dec 17, 2020 at 0:35

3 Answers 3

1

Array.some would be simpler (correct the boolean logic to suit your needs):

const preventOverlapInSchedule = (start, end) => {
  return duties.some(duty => 
      (start >= duty.start && start <= duty.end) ||
      (end >= duty.start && end <= duty.end) ||
      (start <= duty.start && end >= duty.end));
}
Sign up to request clarification or add additional context in comments.

3 Comments

this was nearly perfect except I needed to put an ! in front of duties because I want to return true if the start and end dates do not match any of those conditions.
the ! will work. for maintainability though, it's better to invert all the logical operators accordingly.
taking your advice I modified the conditions to start < duty.start && end < duty.start) || start > duty.end, removed the ! and replaced some with every. Now the function returns true if the new event does not overlap with any of the existing duty events.
1

In JS arr.forEach(callback()) does not return anything. It only executes code for each item in the array with a value.

forEach()

However, arr.map(callback()) calls a function once on each item and returns a new array with any mutation/changes preformed by the callback.

map()

We also have arr.filter(callback()) that will return a new array with each item that is evaluated to true in the callback.

filter()

There is also arr.reduce(callback()) that is a little more complicated, has an accumulator and a next value in the array to compare to. I would recommend looking up all the things this method allows you to do in your code.

reduce()

Comments

0

Have you tried this?

   const preventOverlapInSchedule = (start, end) => {
    duties.forEach(function (duty) {
      if (
        (start >= duty.start && start <= duty.end) ||
        (end >= duty.start && end <= duty.end) ||
        (start <= duty.start && end >= duty.end)
      ) {
        console.log("false");
        return false;
      }

      console.log("true");
      return true;

    });
  };

You are doing a foreach. So there's a logical problem in your code. I think it should behave similarly in Java.

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.