admin管理员组

文章数量:1023187

I have an object that looks like this:

    myObject = {
      publishedDate: string;
      Url: string;
      Title: string;
  }

The property "publishedDate" is a string in the format "19/01/2021". As the example, it can have a date in the future, i.e. a value greater than today. In other words I want to keep all objects where publishedDate is equal or less than today (and delete all that is over). The objects is saved in my state (array):

this.state.data

I first make a date variable for todays value to pare it with publishedDate. I also use moment() to format it in the same date format as the object:

let today = moment().format("DD/MM/YYYY");

I then use a filter method to pare and filter out the data:

  this.state.data.filter(item => new Date(item.publishedDate) >= new Date(today))

And I have also tried:

  this.state.data.filter(function(item) {
    
      if (new Date(item.publishedDate) >= new Date(today)) {
        return false;
      }
    return true;
  });

Not only it does not work, I still have all the objects in the array and nothing is filtered out. What is wrong with the code?

I have an object that looks like this:

    myObject = {
      publishedDate: string;
      Url: string;
      Title: string;
  }

The property "publishedDate" is a string in the format "19/01/2021". As the example, it can have a date in the future, i.e. a value greater than today. In other words I want to keep all objects where publishedDate is equal or less than today (and delete all that is over). The objects is saved in my state (array):

this.state.data

I first make a date variable for todays value to pare it with publishedDate. I also use moment() to format it in the same date format as the object:

let today = moment().format("DD/MM/YYYY");

I then use a filter method to pare and filter out the data:

  this.state.data.filter(item => new Date(item.publishedDate) >= new Date(today))

And I have also tried:

  this.state.data.filter(function(item) {
    
      if (new Date(item.publishedDate) >= new Date(today)) {
        return false;
      }
    return true;
  });

Not only it does not work, I still have all the objects in the array and nothing is filtered out. What is wrong with the code?

Share Improve this question edited Dec 18, 2020 at 19:16 Unmitigated 89.9k12 gold badges99 silver badges104 bronze badges asked Dec 18, 2020 at 19:02 ArteArte 4172 gold badges6 silver badges16 bronze badges 1
  • 1 new Date("19/01/2021") returns: Invalid Date – Davin Tryon Commented Dec 18, 2020 at 19:05
Add a ment  | 

7 Answers 7

Reset to default 2

You can simply use the moment's inbuilt parators like this

this.state.data.filter(item => moment(item.publishedDate,'DD/MM/YYYY').isSameOrAfter(today))

The Date constructor won't accept the format you are currently using, but it will recognize MM/DD/YYYY format. Moreover, filter retains the elements for which the function returns true, so you should be checking if the Date is less than or equal to the current Date.

const today = new Date;
this.state.data = this.state.data.filter(({publishedDate})=>{
    const [d, m, y] = publishedDate.split("/");
    return new Date(m + "/" + d + "/" + y) <= today;
});

Using moment's String + Format initializer and Is Same Or After:

this.state.data.filter(item => moment(item.publishedDate, 'DD/MM/YYYY').isSameOrAfter())

One possibility, using a helper function notAfterToday, which takes a property name (in our case 'publishedDate') and returns a function which takes an object with that property name and reports whether that date is before or on the current date.

It does this by converting, say, the 18th day of December in 2020 into "20201218", and uses that string for the parisons. Note that one advantage of this is that it only calls the Date constructor once, for the initial calculation of today's date.

const data = [{publishedDate: '18/12/2020', Url: 'http://example./1', Title: 'abc'}, {publishedDate: '19/01/2021', Url: 'http://example./2', Title: 'def'}, {publishedDate: '07/04/2014', Url: 'http://example./3', Title: 'ghi'}, {publishedDate: '19/07/2023', Url: 'http://example./4', Title: 'jkl'}, {publishedDate: '05/01/1966', Url: 'http://example./5', Title: 'mno'}, {publishedDate: '01/07/2041', Url: 'http://example./6', Title: 'pqr'}, {publishedDate: '08/05/2061', Url: 'http://example./7', Title: 'stu'}, {publishedDate: '10/08/1999', Url: 'http://example./8', Title: 'vwx'}]

const notAfterToday = (prop) => {
  const reorg = (date, [d, m, y] = date.split('/')) => y + m + d 
  const today = new Date()
  const pare = today .getFullYear() + 
                  String ((today .getMonth () + 1)) .padStart (2, '0') +
                  String (today .getDate ()) .padStart (2, '0')
  return (d) => pare >= reorg (d [prop])
}

console .log (data .filter (notAfterToday ('publishedDate')))
.as-console-wrapper {max-height: 100% !important; top: 0}

At the moment, new Date("19/01/2021") returns: Invalid Date.

This is a possible solution:

let today = moment().format("YYYY-MM-DD");

this.state.data.filter(function(item) {
    const pubDate = item.publishedDate.split('/').reverse().join('-');
    if (new Date(pubDate) >= new Date(today)) {
        return false;
    }
    return true;
});

You have to do a little fine-tuning your date string before paring with today. You can try this-

const data = [
  {
    publishedDate: "19/01/2021",
    url: '',
    title: 'date1'
  },
  {
    publishedDate: "19/05/2021",
    url: '',
    title: 'date2'
  },
  {
    publishedDate: "13/01/2020",
    url: '',
    title: 'date3'
  },
  {
    publishedDate: "16/09/2009",
    url: '',
    title: 'date4'
  },
];

const parseDate = (dateString) => new Date(...dateString.split('/').reverse());


const result = data.filter(item => parseDate(item.publishedDate) <= new Date());

console.log(result);

Storing dates as strings is a code smell. It's harder to pare, store, and convert them as opposed to storing them either as a JS native Date format, or alternatives like Moment.JS date object.

Here is a trivial example of how you could do it if you stored your objects as date.

Notice that the third object got filtered out.

const myObject1 = {
  publishedDate: new Date("2019-01-01"), // NEW
  Url: "whatever",
  Title: "sample",
}

const myObject2 = {
  publishedDate: new Date("2020-01-01"), // NEW
  Url: "whatever",
  Title: "sample",
}

const myObject3 = {
  publishedDate: new Date("2099-01-01"), // NEW
  Url: "whatever",
  Title: "sample",
}

const arr = [myObject1, myObject2, myObject3];

const today = new Date();

const filtered = arr.filter((obj) => obj.publishedDate < today);

console.log(filtered);

I have an object that looks like this:

    myObject = {
      publishedDate: string;
      Url: string;
      Title: string;
  }

The property "publishedDate" is a string in the format "19/01/2021". As the example, it can have a date in the future, i.e. a value greater than today. In other words I want to keep all objects where publishedDate is equal or less than today (and delete all that is over). The objects is saved in my state (array):

this.state.data

I first make a date variable for todays value to pare it with publishedDate. I also use moment() to format it in the same date format as the object:

let today = moment().format("DD/MM/YYYY");

I then use a filter method to pare and filter out the data:

  this.state.data.filter(item => new Date(item.publishedDate) >= new Date(today))

And I have also tried:

  this.state.data.filter(function(item) {
    
      if (new Date(item.publishedDate) >= new Date(today)) {
        return false;
      }
    return true;
  });

Not only it does not work, I still have all the objects in the array and nothing is filtered out. What is wrong with the code?

I have an object that looks like this:

    myObject = {
      publishedDate: string;
      Url: string;
      Title: string;
  }

The property "publishedDate" is a string in the format "19/01/2021". As the example, it can have a date in the future, i.e. a value greater than today. In other words I want to keep all objects where publishedDate is equal or less than today (and delete all that is over). The objects is saved in my state (array):

this.state.data

I first make a date variable for todays value to pare it with publishedDate. I also use moment() to format it in the same date format as the object:

let today = moment().format("DD/MM/YYYY");

I then use a filter method to pare and filter out the data:

  this.state.data.filter(item => new Date(item.publishedDate) >= new Date(today))

And I have also tried:

  this.state.data.filter(function(item) {
    
      if (new Date(item.publishedDate) >= new Date(today)) {
        return false;
      }
    return true;
  });

Not only it does not work, I still have all the objects in the array and nothing is filtered out. What is wrong with the code?

Share Improve this question edited Dec 18, 2020 at 19:16 Unmitigated 89.9k12 gold badges99 silver badges104 bronze badges asked Dec 18, 2020 at 19:02 ArteArte 4172 gold badges6 silver badges16 bronze badges 1
  • 1 new Date("19/01/2021") returns: Invalid Date – Davin Tryon Commented Dec 18, 2020 at 19:05
Add a ment  | 

7 Answers 7

Reset to default 2

You can simply use the moment's inbuilt parators like this

this.state.data.filter(item => moment(item.publishedDate,'DD/MM/YYYY').isSameOrAfter(today))

The Date constructor won't accept the format you are currently using, but it will recognize MM/DD/YYYY format. Moreover, filter retains the elements for which the function returns true, so you should be checking if the Date is less than or equal to the current Date.

const today = new Date;
this.state.data = this.state.data.filter(({publishedDate})=>{
    const [d, m, y] = publishedDate.split("/");
    return new Date(m + "/" + d + "/" + y) <= today;
});

Using moment's String + Format initializer and Is Same Or After:

this.state.data.filter(item => moment(item.publishedDate, 'DD/MM/YYYY').isSameOrAfter())

One possibility, using a helper function notAfterToday, which takes a property name (in our case 'publishedDate') and returns a function which takes an object with that property name and reports whether that date is before or on the current date.

It does this by converting, say, the 18th day of December in 2020 into "20201218", and uses that string for the parisons. Note that one advantage of this is that it only calls the Date constructor once, for the initial calculation of today's date.

const data = [{publishedDate: '18/12/2020', Url: 'http://example./1', Title: 'abc'}, {publishedDate: '19/01/2021', Url: 'http://example./2', Title: 'def'}, {publishedDate: '07/04/2014', Url: 'http://example./3', Title: 'ghi'}, {publishedDate: '19/07/2023', Url: 'http://example./4', Title: 'jkl'}, {publishedDate: '05/01/1966', Url: 'http://example./5', Title: 'mno'}, {publishedDate: '01/07/2041', Url: 'http://example./6', Title: 'pqr'}, {publishedDate: '08/05/2061', Url: 'http://example./7', Title: 'stu'}, {publishedDate: '10/08/1999', Url: 'http://example./8', Title: 'vwx'}]

const notAfterToday = (prop) => {
  const reorg = (date, [d, m, y] = date.split('/')) => y + m + d 
  const today = new Date()
  const pare = today .getFullYear() + 
                  String ((today .getMonth () + 1)) .padStart (2, '0') +
                  String (today .getDate ()) .padStart (2, '0')
  return (d) => pare >= reorg (d [prop])
}

console .log (data .filter (notAfterToday ('publishedDate')))
.as-console-wrapper {max-height: 100% !important; top: 0}

At the moment, new Date("19/01/2021") returns: Invalid Date.

This is a possible solution:

let today = moment().format("YYYY-MM-DD");

this.state.data.filter(function(item) {
    const pubDate = item.publishedDate.split('/').reverse().join('-');
    if (new Date(pubDate) >= new Date(today)) {
        return false;
    }
    return true;
});

You have to do a little fine-tuning your date string before paring with today. You can try this-

const data = [
  {
    publishedDate: "19/01/2021",
    url: '',
    title: 'date1'
  },
  {
    publishedDate: "19/05/2021",
    url: '',
    title: 'date2'
  },
  {
    publishedDate: "13/01/2020",
    url: '',
    title: 'date3'
  },
  {
    publishedDate: "16/09/2009",
    url: '',
    title: 'date4'
  },
];

const parseDate = (dateString) => new Date(...dateString.split('/').reverse());


const result = data.filter(item => parseDate(item.publishedDate) <= new Date());

console.log(result);

Storing dates as strings is a code smell. It's harder to pare, store, and convert them as opposed to storing them either as a JS native Date format, or alternatives like Moment.JS date object.

Here is a trivial example of how you could do it if you stored your objects as date.

Notice that the third object got filtered out.

const myObject1 = {
  publishedDate: new Date("2019-01-01"), // NEW
  Url: "whatever",
  Title: "sample",
}

const myObject2 = {
  publishedDate: new Date("2020-01-01"), // NEW
  Url: "whatever",
  Title: "sample",
}

const myObject3 = {
  publishedDate: new Date("2099-01-01"), // NEW
  Url: "whatever",
  Title: "sample",
}

const arr = [myObject1, myObject2, myObject3];

const today = new Date();

const filtered = arr.filter((obj) => obj.publishedDate < today);

console.log(filtered);

本文标签: javascriptCompare and filter out date properties in a objectStack Overflow