0

I have a while loop that should iterate through an array and the selectedDate value to determine if an event will fall on the weekend coming, however it is not filtering out the results correctly and I am unsure why, everything looks correct to me. Is the while loop the correct tool for this sorting job?

Function

  function(err,results) {
    var i = results.length;
    var theWeekend = [];
    //console.log(results)

    // EVERYTHING WORKS UNTIL HERE
    while(i--) {
      if (0 >= [friday, saturday, sunday].indexOf(results[i].selectedDate)) {
          theWeekend.push(results[i]);
          //console.log(theWeekend);
        }
    }
    callback(err, theWeekend)
    console.log(theWeekend);
    }

The [friday, saturday, sunday] gives the correct dates to the console:

[ Fri Apr 08 2016 14:00:54 GMT+0100 (BST),
  Sat Apr 09 2016 14:00:54 GMT+0100 (BST),
  Sun Apr 10 2016 14:00:54 GMT+0100 (BST) ]

The anticipate result should be:

[ { _id: 570260718ef368db32c570c8,
    url: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators',
    title: 'Expressions and operators - JavaScript | MDN',
    selectedDate: Sun Apr 10 2016 01:00:00 GMT+0100 (BST),
    __v: 0 } ]

However I am receiving data that has the previous weekend, which should be omitted:

[ { _id: 56fffb5ceb76276c8f39e3f3,
    url: 'http://londonist.com/2015/11/where-to-eat-and-drink-in-balham',
    title: 'Where To Eat And Drink In... Balham  | Londonist',
    selectedDate: Fri Apr 01 2016 01:00:00 GMT+0100 (BST),
    __v: 0 },
  { _id: 570260738ef368db32c570c9,
    url: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators',
    title: 'Expressions and operators - JavaScript | MDN',
    selectedDate: Sun Apr 10 2016 01:00:00 GMT+0100 (BST),
    __v: 0 },
  { _id: 56fffb8eeb76276c8f39e3f5,
    url: 'https://news.ycombinator.com/item?id=11404770',
    title: 'The Trouble with CloudFlare | Hacker News',
    selectedDate: Sun Apr 03 2016 01:00:00 GMT+0100 (BST),
    __v: 0 },
  { _id: 56fffb6ceb76276c8f39e3f4,
    url: 'http://wellnessmama.com/13700/benefits-coconut-oil-pets/',
    title: 'Benefits of Coconut Oil for Pets - Wellness Mama',
    selectedDate: Sat Apr 02 2016 01:00:00 GMT+0100 (BST),
    __v: 0 } ]
1
  • 1
    I think that the issue is indexOf function since you are trying to compare date objects, i.e. there's no way that any of them will match even if they point at the same date because these are different objects in memory. Commented Apr 4, 2016 at 13:19

3 Answers 3

2

I think that the issue is the .indexOf function. I assume that you are using Date objects. Have a look at this:

> var x = new Date(2000, 1, 1);
> var y = new Date(2000, 1, 1);
> x === y
false

That's because these are different objects even though they point at the same date. So .indexOf has to fail because it uses === internally.

I think you have to do more complicated thing and actually compare dates:

var days = [friday, saturday, sunday];
var theWeekend = results.filter(function(obj) {
    for (var i = 0; i < days.length; i++) {
        var day = days[i];
        // now properly compare the day of week
        if (day.getDay() == obj.selectedDate.getDay()) {
            return true;
        }
    }
    return false;
});

or something like this depending on what you really are after.

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

3 Comments

This is actually pretty spot on. Instead of calling getDay on the date objects and comparing it, which would always return any given fri - sun, I can use the getDate method and compare the two to match the upcoming weekend. Thank you. One tiny point on indexOf is that it uses strict equality according to MDN.
@RhysEdwards Right, right, getDate ftw. As for indexOf I've fixed it in my answer. Thanks for spotting.
@RhysEdwards Also note that this can be even further simplified by doing results.map(...).filter(...) with var days = [friday.getDate(), ...]. If you know what I mean. However it won't be as efficient (since temporary list will be produced). Not that it matters.
1

If the item isn't found, indexOf returns -1.

When 0 >= -1 (which is the case when the item isn't found), your expression is true.

This is probably why you're not getting the result you're expecting?

Edit: you might want to look into a map or filter function for your array. There are multiple such utility functions available, are you using any JS frameworks for your app?

2 Comments

So if only one item returns true, the rest will still be pushed to the array which is why it's not filtering? I will look into map and filter. The app is node / express for all the server-side, everything else is pretty vanilla.
I think the problem might be that your expression is inadvertently inverted? Your loop will only push the item to the array if the item isn't found in your comparison array. Also, you should probably just compare the date component, to avoid the actual time (hours/minutes) messing up your comparison.
0

You have a couple of issues. First, your if statement is reversed. It is pushing all the cases where indexOf returns less than 0, but you want it to push all the cases where it is greater than or equal to 0. Also, it seems that indexOf using Date objects doesn't work. One solution to this is to convert them into integers first.

Also, I made a few tweaks to your code. First, I would create the weekend dates array only once (you are currently recreating it each iterating). Second, your while loop is just a for loop, so I would use an actual for loop, since it will be easier for others to read.

function(err, results) {
  var theWeekend = [],
    weekendDates = [friday.getTime(), saturday.getTime(), sunday.getTime()],
    i;

  for (i = results.length - 1; i >= 0; i--) {
    if (weekendDates.indexOf(results[i].selectedDate.getTime()) >= 0) {
      theWeekend.push(results[i]);
    }
  }

  callback(err, theWeekend);
};

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.