0

I'm new to JavaScript and I have an array of JSON objects with some attributes. I want to sort it by date attribute, which can be either date or bool. I think an example will help you understand my problem.

[
    {
        "name":"Name 1",
        "photoUrl":"URL",
        "date" : false,
        "bool": false
    },
    {
        "name":"Name2",
        "photoUrl":"URL",
        "date" : false,
        "bool": false
    },
    {
        "name":"Name 3",
        "photoUrl":"URL",
        "date" : "1.6. 2020",
        "bool": true
    },
    {
        "name":"Name 4",
        "photoUrl":"",
        "date" : "25.9. 2020",
        "bool": true
    },
{
        "name":"Name 5",
        "photoUrl":"",
        "date" : "29.8. 2020",
        "bool": true
    },
{
        "name":"Name 6",
        "photoUrl":"",
        "date" : "4.7. 2020",
        "bool": true
    },
{
        "name":"Name 7",
        "photoUrl":"",
        "date" : "25.6. 2020",
        "bool": true
    },
{
        "name":"Name 8",
        "photoUrl":"",
        "date" : "22.2. 2021",
        "bool": true
    },
]

I can change the data structure however I want. Basically, I want the ones with the date not false on top of my array and sorted by the date (newest on top) and then follow with the ones with date false, but I can't find a way to do that.

Thanks much for any help.

2 Answers 2

1
var ls = [
            {
                "name":"Name 1",
                "photoUrl":"URL",
                "date" : false,
                "bool": false
            },
            {
                "name":"Name2",
                "photoUrl":"URL",
                "date" : false,
                "bool": false
            },
            {
                "name":"Name 3",
                "photoUrl":"URL",
                "date" : "1.6. 2020",
                "bool": true
            },
            {
                "name":"Name 4",
                "photoUrl":"",
                "date" : "25.9. 2020",
                "bool": true
            },
        {
                "name":"Name 5",
                "photoUrl":"",
                "date" : "29.8. 2020",
                "bool": true
            },
        {
                "name":"Name 6",
                "photoUrl":"",
                "date" : "4.7. 2020",
                "bool": true
            },
        {
                "name":"Name 7",
                "photoUrl":"",
                "date" : "25.6. 2020",
                "bool": true
            },
        {
                "name":"Name 8",
                "photoUrl":"",
                "date" : "22.2. 2021",
                "bool": true
            },
        ];
        


function customSort(ls){
         
         var lsWithDatesAsBool = ls.filter((obj)=>{ return (typeof(obj.date)=="boolean") });
         var lsWithDatesAsNotBool = ls.filter((obj)=>{ return !(typeof(obj.date)=="boolean") });
         lsWithDatesAsNotBool.sort((a, b) => (convertToProperDate(a.date) < convertToProperDate(b.date)) ? 1 : -1)
         return lsWithDatesAsNotBool.concat(lsWithDatesAsBool);
        
        }
        
 function convertToProperDate(d)
        {
        var arr = d.split(".");
        var day = arr[0].trim();
        var month=arr[1].trim();
        var year = arr[2].trim();
        console.log(year+"-"+(month.length==1?("0"+month):month)+"-"+(day.length==1?("0"+day):day))
        return new Date(year+"-"+(month.length==1?("0"+month):month)+"-"+(day.length==1?("0"+day):day))
        }
    
console.log(customSort(ls));
Sign up to request clarification or add additional context in comments.

4 Comments

It works, but if I add more data (i updated the question with more data) it doesn't work correctly, that's my bad, I thought less data is good enough to make it work.
@krystof18 , It's because your date format is not proper so sorting is inaccurate. Have updated the solution now, hope it helps!!
All the brackets and braces in (obj)=>{ return (typeof(obj.date)=="boolean") } are redundant, use obj => typeof obj.date == 'boolean'.
In the date parser, it makes no sense to parse a string to another string that is then parsed by the built–in parser as UTC. Consider let [d, m, y] = d.split(/\D+/); return new Date(y, m-1, d) to avoid the built–in parser entirely. The \D+ splits on one or more non–digit characters to handle cases like "25.6. 2020".
0

I'm also new and this worked, maybe it's not the best practice.

const data = [
  {
    name: "Name 1",
    photoUrl: "URL",
    date: false,
    bool: false,
  },
  {
    name: "Name2",
    photoUrl: "URL",
    date: false,
    bool: false,
  },
  {
    name: "Name 3",
    photoUrl: "URL",
    date: "1.6. 2020",
    bool: true,
  },
  {
    name: "Name 4",
    photoUrl: "",
    date: "25.9. 2020",
    bool: true,
  },
];

const sortingData = () => {
  let sortedData = [];

  //Getting data with date and adding them to the empty array.
  for (let i = 0; i < data.length; i++) {
    if (data[i].date) {
      sortedData.push(data[i]);
    }
  }
  //Sorting from new to old.
  sortedData.sort((a, b) => (a.date < b.date ? 1 : -1));

  //Getting data with no date and adding them to the new array.
  for (let i = 0; i < data.length; i++) {
    if (data[i].date === false) {
      sortedData.push(data[i]);
    }
  }
  return sortedData;
};

2 Comments

It works, but if I add more data (i updated the question with more data) it doesn't work correctly, that's my bad, I thought less data is good enough to make it work.
No, it doesn't "work" because dates in the format d.m.y do not sort lexically. A format like yyyy-mm-dd does. Also, the sort function should return 0 when a.date == b.date, your function returns 1, so might as well be (a, b) => a.date < b.date.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.