【问题标题】:How to Filter Data Array by Week Filter()如何按周过滤器过滤数据数组()
【发布时间】:2019-04-15 06:32:26
【问题描述】:

目前尝试按周过滤我的数据数组,我已经能够很容易地按天过滤,但是我在 x 和 y 之间的日期(例如按周)上苦苦挣扎。

我尝试设置开始日期和结束日期(今天),然后尝试返回小于或等于开始日期和结束日期的日期,但失败了。

数据数组日期格式:dd/mm/yyyy (01/01/2000)

用户将选择使用哪个过滤器(因此 switch() )案例 7 被过滤 7 天。

computed: {
    appointments: function () {

      var today = new Date();
      var dd = String(today.getDate()).padStart(2, '0');
      var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
      var yyyy = today.getFullYear();


      var data = this.$store.state.appointments;

      this.filter1_color = "grey";
      this.filter2_color = "grey";

      switch (this.dateFilter) {
        case 0:
        break;

        case 1:
        console.log("case1: " + today)
        return data.filter(word => word.date == today);

        case 7:

        /// WORKING /// (ex. edit)
        var week = [];

        var today = moment();
        var sevenDaysBefore = today.subtract(7, 'days');

        for (var i = 0; i < data.length; i++) {
          let momentDate = moment(data[i].date, 'DD/MM/YYYY')
          let newDate = momentDate.format("DD/MM/YYYY")
          if (momentDate.isBetween(sevenDaysBefore, moment(), null, '[]')) week.push(data[i]);
        }


        return week
        ///

      }


      return data;
    },

我需要过滤数据以仅显示数组中日期等于过去 7 天日期的项目。

【问题讨论】:

  • 能用moment js这样的库吗?
  • @f-CJ 可以,我刚刚安装了它,看起来很方便 - 不过仍然需要找到解决方案。
  • 是的。您需要获得本周或最近 7 天内的所有约会结果吗?
  • @f-CJ 仅过去 7 天就是我想要做的。

标签: javascript vue.js


【解决方案1】:

您可以使用当前日期的时刻 js 库的方法 isBetween。您可以使用subtract(7, 'days') 减去当前日期的 7 天。

您可以在 Moment js 库文档中查看更多关于 isBetween 方法的信息。该方法的第三个参数是粒度,在您的情况下似乎应该是“天”

const today = moment();
const sevenDaysBefore = moment().subtract(7, 'days');

console.log('Today is ' + today.format('MMM Do YYYY'));
console.log('Is ' + today.format('MMM Do YYYY') + ' included in the last seven days?');
console.log(today.isBetween(sevenDaysBefore, today, 'day', '[]'));

console.log('Is ' + sevenDaysBefore.format('MMM Do YYYY') + ' included in the last seven days?');
console.log(sevenDaysBefore.isBetween(sevenDaysBefore, today, 'day', '[]'));

const eightDaysBefore = moment().subtract(8, 'days');
console.log('Is ' + eightDaysBefore.format('MMM Do YYYY') + ' included in the last seven days?');
console.log(eightDaysBefore.isBetween(sevenDaysBefore, today, 'day', '[]'));

const oneDayAfter = moment().add(1, 'days');
console.log('Is ' + oneDayAfter.format('MMM Do YYYY') + ' included in the last seven days?');
console.log(oneDayAfter.isBetween(sevenDaysBefore, today, 'day', '[]'));
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"&gt;&lt;/script&gt;

【讨论】:

  • 添加了另一个答案,以防 OP 无法使用 moment.js。但是,赞成并推荐了您的答案。
  • @f-CJ 谢谢。它基本上得到了我需要的东西,但我在实施它时遇到了麻烦。我已经设置了一个 for 循环来过滤掉它们(请参阅我在 /// EDIT /// 之间更新的代码 - 但得到 TypeError: e[i].date.isBetween is not a function 这很令人困惑,因为它在将它放在自己的 if 语句中时会起作用。我是否正在尝试这样做艰难的道路?
  • @TimRowley 您必须解析 date 才能将其转换为 momentisBetween 是一种矩方法。可能只是使用moment(data.date[i], 'DD/MM/YYYY') 你很好,但请查看文档momentjs.com/docs/#/parsing
  • 我的意思是moment(data[i].date, 'DD/MM/YYYY')
  • @f-CJ 太好了 - 谢谢你,现在它变得更有意义了。我现在已经把它带到了一个工作状态,这太棒了,肯定会用 Moment JS 让生活更轻松。 (向 OP 添加了工作代码)
【解决方案2】:

如果您不想或不能使用像 moment.js 这样的库,并且也不介意具有某些限制的临时实现:

注意

我建议使用库来处理Date 对象,尤其是在将字符串解析为日期时。手动操作时可能会出错。如果可能,请使用@f-CJ 的答案

这些部分允许您从字符串创建Date 对象。但是,生成的Date总是转换为本地时间,并且字符串需要具有某种格式(您在问题中显示的格式)。如果您需要UTC 支持,这将不起作用。此外,它不能用于解析具有 ISO 格式的日期字符串

const OFFSET_TO_UTC = new Date().getTimezoneOffset();

function parseDateString (dateString, sep) {
  var parts = dateString.split(sep);
  return parts.map(n => Number(n));
}

function localizeDate (pattern, parts) {
  return pattern.reduce((acc, pat, i) => {
    switch (pat) {
      case 'd':
        return Object.assign(acc, { day: parts[i] });
      case 'm':
        return Object.assign(acc, { month: parts[i] });
      case 'y':
        return Object.assign(acc, { year: parts[i] });
      default:
        return acc;
    }
  }, {});
}

function toDate (localized) {
  return new Date(
    localized.year,
    localized.month - 1,
    localized.day,
    0, 0 - OFFSET_TO_UTC, 0);
}

function parseDate (pattern, sep, dateString) {
  return toDate(localizeDate(pattern, parseDateString(dateString, sep)));
}


// try it:

const dStringUS = '04/04/2019'; // mm/dd/yyyy
const dStringDE = '04.04.2019'; // dd/mm/yyyy

const dateUS = parseDate(['m', 'd', 'y'], '/', dStringUS);
const dateDE = parseDate(['d', 'm', 'y'], '.', dStringDE);

console.log(dateUS);
console.log(dateDE);

基于它,你可以自己写一个通用的过滤函数:

const OFFSET_TO_UTC = new Date().getTimezoneOffset();

function parseDateString (dateString, sep) {
  var parts = dateString.split(sep);
  return parts.map(n => Number(n));
}

function localizeDate (pattern, parts) {
  return pattern.reduce((acc, pat, i) => {
    switch (pat) {
      case 'd':
        return Object.assign(acc, { day: parts[i] });
      case 'm':
        return Object.assign(acc, { month: parts[i] });
      case 'y':
        return Object.assign(acc, { year: parts[i] });
      default:
        return acc;
    }
  }, {});
}

function toDate (localized) {
  return new Date(
    localized.year,
    localized.month - 1,
    localized.day,
    0, 0 - OFFSET_TO_UTC, 0);
}

function parseDate (pattern, sep, dateString) {
  return toDate(localizeDate(pattern, parseDateString(dateString, sep)));
}



const data = [{
  value: 0,
  date: '04/05/2019'
}, {
  value: 1,
  date: '04/07/2019'
}, {
  value: 2,
  date: '03/07/2019'
}];

function filterByDatePattern (pattern, sep) {
  return function (date, list) {
    return list.filter(item => {
      var itemDate = parseDate(pattern, sep, item.date);
      return itemDate >= date;
    });
  }
}

const onlyUSUntil = filterByDatePattern(['m', 'd', 'y'], '/');
console.log(onlyUSUntil(new Date(2019, 3, 1), data));

【讨论】:

  • 谢谢大卫,看起来确实很难实现。欣赏它:)
猜你喜欢
  • 2022-01-23
  • 2022-12-07
  • 2014-01-12
  • 1970-01-01
  • 2011-02-15
  • 2022-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多