【问题标题】:How to check if two arrays of dates have matching items?如何检查两个日期数组是否有匹配项?
【发布时间】:2016-09-30 08:14:02
【问题描述】:

我有两个日期数组。第一个包含所有预订日期,第二个包含用户将选择的“开始日”和“结束日”之间的日期。

现在我必须确认从完全预订的日期数组中找不到开始和停止之间的天数。

我正在使用 Vue.js 来更新数据。

这是我为获取这些日期所做的工作:

          /**
           * Get dates from datepicker and format it to the same format that fully booked array has it's dates.
          **/                
            var day1 = moment( this.startDate, 'DD/MM/Y').format('Y,M,D');
            var day2 = moment( this.endDate, 'DD/MM/Y').format('Y,M,D');
            var start = new Date(day1);
            var end = new Date(day2);

          /**
           * Get dates between start and stop and return them in the dateArray.
          **/ 
            Date.prototype.addDays = function(days) {
              var dat = new Date(this.valueOf());
              dat.setDate(dat.getDate() + days);
              return dat;
            };

            function getDates(startDate, stopDate) {
              var dateArray = [];
              var currentDate = startDate;
                while (currentDate <= stopDate) {
                  dateArray.push(currentDate);
                  currentDate = currentDate.addDays(1);
                }
              return dateArray;
            }

            var dateArray = getDates(start, end);

          /**
           * Set dateArray in to Vue.js data.
          **/ 
            this.$set('daysBetweenStartStop', dateArray);

          /**
           * Get arrays of dates from the Vue.js data. calendar = Booked dates | matchingDays = Dates between start and stop.
          **/ 
            var calendar = this.fullDates;
            var matchingDays = this.daysBetweenStartStop;

          /**
            * @description determine if an array contains one or more items from another array.
            * @param {array} haystack the array to search.
            * @param {array} arr the array providing items to check for in the haystack.
            * @return {boolean} true|false if haystack contains at least one item from arr.
          */
            var findIfMatch = function (haystack, arr) {
                return arr.some(function (v) {
                    return haystack.indexOf(v) >= 0;
                });
            };
            var matching = findIfMatch(calendar, matchingDays);

          /**
           * Check the results. If false we are good to go.
          **/ 
            if (matching){
              alert('WE FOUND A MATCH');
            } else {
              alert('GOOD TO GO');
            }

数组的格式如下:

var calendar = [
Sun Oct 02 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 09 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 16 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 23 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 30 2016 00:00:00 GMT+0300 (EEST)
]

var matchingDays = [
Fri Oct 28 2016 00:00:00 GMT+0300 (EEST),
Sat Oct 29 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 30 2016 00:00:00 GMT+0300 (EEST)
]

我的问题是,即使这两个数组具有完全相同的日期,它们仍然会以某种方式被视为不相同。任何想法如何让它工作?

【问题讨论】:

  • 数组总是排序的吗?
  • 您的意思是您需要查看两个数组之间的差异还是需要查看数组中的匹配项?
  • @Gal 是的,完全预订的数组来自其他函数,该函数从另一个数组中过滤特定日期,然后将它们设置在完全预订的数组中。匹配天数数组来自开始日和结束日,它将从开始到结束将项目推送到数组。
  • @Deepakrao 必须检查 matchDay 数组中是否有任何日期在日历数组中。所以我需要查看数组中的匹配项。 (如果有匹配的日期 -> 返回 true)
  • 一个日期是一个对象,两个日期对象永远不会相等。最好的选择是将日期转换为字符串或数字等。

标签: javascript arrays date vue.js


【解决方案1】:

你的匹配函数应该是这样的:

findIfMatch = function (haystack, arr){
      var i = 0;//array index
      var j = 0;//array index
      while(j < arr.length && i < haystack.length){

          cur_cal = Date.parse(haystack[i]);
          cur_match = Date.parse(arr[j]);
          if(cur_cal > cur_match){
              j++;
          }else if(cur_cal < cur_match){
              i++;
          }else{
              return true;
          }
      }
      return false;
}

【讨论】:

  • 很好,我喜欢这种方法,因为它不会构建新数组。
【解决方案2】:

要从两个数组中获取匹配记录,请使用此

var calendar =  [
Sun Oct 02 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 09 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 16 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 23 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 30 2016 00:00:00 GMT+0300 (EEST)
];
var matchingDays = [
Fri Oct 28 2016 00:00:00 GMT+0300 (EEST),
Sat Oct 29 2016 00:00:00 GMT+0300 (EEST),
Sun Oct 30 2016 00:00:00 GMT+0300 (EEST)
];
var newCalendar = [];
var newMatchingDays = []
$.map(calendar, function(date){
    newCalendar.push(date.toString())
});

$.map(matchingDays, function(date){
    newMatchingDays.push(date.toString())
});

var result = [];
$.map(newCalendar, function (val, i) {
    if ($.inArray(val, newMatchingDays) > -1) {
        result.push(val);
    }
});
console.log(result);

【讨论】:

  • 啊,完美。所以基本上我现在需要检查的是 result.length === 0,以便为我的任务获得正确的真假?
  • 如果您不介意使用第三方库,请查看下划线交集,我将更新我的答案以显示示例。
  • ya 现在下划线已更改为 lodash 它非常适合对象数组操作
【解决方案3】:

首先你不能像那样比较日期,Date 是一个对象。 例如。

var d1 = new Date('2016-09-30');
var d1 = new Date('2016-09-30');
console.log(d1 === d2); // = false

您需要循环数组并比较每个项目,而不是使用 indexOf。 或者也许使用 Array.filter()。或者使用和对象作为查找。

例如。如果说你有 ->

var calendar = {
   "Sun Oct 02 2016 00:00:00 GMT+0300 (EEST)": true,
   "Sun Oct 09 2016 00:00:00 GMT+0300 (EEST)": true,
   "Sun Oct 16 2016 00:00:00 GMT+0300 (EEST)": true,
   "Sun Oct 23 2016 00:00:00 GMT+0300 (EEST)": true,
   "Sun Oct 30 2016 00:00:00 GMT+0300 (EEST)": true
};
if (calendar["Sun Oct 16 2016 00:00:00 GMT+0300 (EEST)"]) {
   console.log("We have date");
}

请注意我如何使用字符串表示日期,这也可以是一个数字,例如。来自 Date.getTime()。

这里使用的是 Array.filter,我认为它没有对象查找那么快。但是我们开始了。

var calendar = [
   new Date('2016-09-01'),
   new Date('2016-09-12'),
   new Date('2016-09-10')
];

var finddate = new Date('2016-09-12');
var found = calendar.filter(function (a) { return a.getTime() === finddate.getTime();});

如果您不介意使用第三方库,请尝试下划线..

例如。

var days = [new Date('2016-09-01'), new Date('2016-09-10'), new Date('2016-09-30')];
var finddays = [new Date('2016-09-01'), new Date('2016-09-30')];

var found = _.intersectionWith(days, finddays, 
   function (a,b) { return a.getTime() === b.getTime(); });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 2018-01-16
    • 2017-07-07
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多