4

I am trying to sort data based on descending order of publishDate but it's not working. In some array, publishDate is coming and in some array, it's not coming.

[
    {
        "id": "brexit-delay",
        "title": "Brexit Delay",
        "publish": {

            "publishDate": "2019-8-30T12:25:47.938Z",
        }
    },   

    {
        "id": "brexit-delay",
        "title": "Example 3"
    },    

    {
        "id": "brexit-delay",
        "title": "Example 2",
        "publish": {           
            "publishDate": "2019-6-30T12:25:47.938Z",
        }
    },

    {
        "id": "brexit-delay",
        "title": "Example 5"
    },    

    {
        "id": "brexit-delay",
        "title": "Example 5",
        "publish": {           
            "publishDate": "2019-10-25T12:25:47.938Z",
        }
    }
]   

Js code:

data.sort(function(a, b){
    if("publish" in a && "publish" in b){
        return new Date(a.publish.publishDate) - new Date(b.publish.publishDate)
    }
} );
5
  • And how would you like to treat those objects where the publishDate is missing? Are they later that everything or sooner? Commented Dec 20, 2019 at 7:37
  • Additionally, you are checking 'publish' in a while the key is called publishDate in the original object, so I guess it should be 'publishDate' in a Commented Dec 20, 2019 at 7:39
  • @SebastianKaczmarek publishDate is a key of publish, so it doesn't matter. I'm assuming that if publish key exist then publish.publishDate will also have some date value. Commented Dec 20, 2019 at 7:40
  • @SebastianKaczmarek i want object without publishDate treat as sooner Commented Dec 20, 2019 at 7:42
  • @hussain.codes ah, sorry, you are right. I didn't see the publish key ;) Commented Dec 20, 2019 at 7:44

3 Answers 3

3

Check whether the property exists and based on this return order:

const myParseDate = date_string => {
    let [y,M,d,h,m,s] = date_string.split(/[- :T]/);
    return new Date(y,parseInt(M)-1,d,h,parseInt(m),s.replace('Z',''));
}

arr.sort(function(a, b){
    if (a.publish  && b.publish) {
        return myParseDate(b.publish.publishDate) - myParseDate(a.publish.publishDate)
    }
    else if (a.hasOwnProperty("publish"))
        return -1;
    else if (b.hasOwnProperty("publish"))
        return 1;
    else
        return 0;
} );

An example:

const arr = [
{
    "id": "brexit-delay",
    "title": "Brexit Delay",
    "publish": {
        "publishDate": "2019-8-30T12:25:47.938Z",
    }
},
{
    "id": "brexit-delay",
    "title": "Example 3"
},
{
    "id": "brexit-delay",
    "title": "Example 2",
    "publish": {
        "publishDate": "2019-6-30T12:25:47.938Z",
    }
},
{
    "id": "brexit-delay",
    "title": "Example 5"
},
{
    "id": "brexit-delay",
    "title": "Example 5",
    "publish": {
        "publishDate": "2019-10-25T12:25:47.938Z",
    }
}
]

const myParseDate = date_string => {
let [y,M,d,h,m,s] = date_string.split(/[- :T]/);
return new Date(y,parseInt(M)-1,d,h,parseInt(m),s.replace('Z',''));
}

arr.sort(function(a, b){    
if (a.publish  && b.publish)
    return myParseDate(b.publish.publishDate) - myParseDate(a.publish.publishDate)
else if (a.hasOwnProperty("publish"))
    return -1;
else if (b.hasOwnProperty("publish"))
    return 1;
else
    return 0;
} );

console.log(arr);

UPDATE:

If you want ascending order, then just change place of a and b:

arr.sort(function(a, b){
    if (a.publish  && b.publish)
        return myParseDate(a.publish.publishDate) - myParseDate(b.publish.publishDate)
    else if (a.hasOwnProperty("publish"))
        return -1;
    else if (b.hasOwnProperty("publish"))
        return 1;
    else
        return 0;
} );

An example:

const arr = [
    {
        "id": "brexit-delay",
        "title": "Brexit Delay",
        "publish": {
            "publishDate": "2019-8-30T12:25:47.938Z",
        }
    },
    {
        "id": "brexit-delay",
        "title": "Example 3"
    },
    {
        "id": "brexit-delay",
        "title": "Example 2",
        "publish": {
            "publishDate": "2019-6-30T12:25:47.938Z",
        }
    },
    {
        "id": "brexit-delay",
        "title": "Example 5"
    },
    {
        "id": "brexit-delay",
        "title": "Example 5",
        "publish": {
            "publishDate": "2019-10-25T12:25:47.938Z",
        }
    }
]

const myParseDate = date_string => {
    let [y,M,d,h,m,s] = date_string.split(/[- :T]/);
    return  new Date(y,parseInt(M)-1,d,h,parseInt(m),s.replace('Z',''));
}

arr.sort(function(a, b){
    if (a.publish  && b.publish)
        return myParseDate(a.publish.publishDate) - myParseDate(b.publish.publishDate)
    else if (a.hasOwnProperty("publish"))
        return -1;
    else if (b.hasOwnProperty("publish"))
        return 1;
    else
        return 0;
} );

console.log(arr);

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

5 Comments

According to output of your code this Example 2 is coming on 2nd position but it should be on first position.
@Addy Example2 has 2019-6-30T12:25:47.938Z, however Brexit Delay is 2019-8-30T12:25:47.938Z and it is descending order
What changes, i need to made if i want asc order
your code working fine with js execution. But i am trying to use code in node js i get issue with array which don't have date.
@Addy as a good practice at stackoverflow, it is better to have one question per post. Could you create a new post with error?
0

a sort function must return a number. you have an if statement inside your sort compare function with and comparator, so if some object does not have publish date, the compare function does not return anything, you might try to place more if's

a.sort((a, b) => {
    if (a.publish && b.publish) {
        return //compare condition
    } else if (a.publish && !b.publish) {
        return //compare condition
    } else if (!a.publish && b.publish) {
        return //compare condition
    } else {
        return //compare condition
    }
});

Comments

0

You need to update your code to this:

data.sort(function(a, b){
    if("publish" in a && "publish" in b){
        return new Date(a.publish.publishDate.replace("T", " ") - new Date(b.publish.publishDate.replace("T", " "))
    }
} );

new Date("2019-10-25T12:25:47.938Z") just returns the string "Invalid Date" unless you replace the "T"

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.