0

I've read the previous question on this topic: Lodash : how to do a case insensitive sorting on a collection using orderBy?

I found that lodash correctly sorts numeric and date columns. I need case-insensitive sorting for the string columns. We currently have the following implementation:

const sorted = _.orderBy(this, function (o)  {
            if ($.isNumeric(o[column])) {
                return parseFloat(o[column]);
            }

            return (o[column]).toLowerCase();
        }, direction);
        
        this.clear();
    
        for (let i = 0; i < sorted.length; i++) {
            this.push(sorted[i]);
        }

My concern is that implementation is not going to handle dates properly. Do we need anything special here for dates?

Naomi
  • 718
  • 1
  • 9
  • 28
  • 1
    Why not just try? Are the dates string? – FINDarkside May 31 '18 at 12:18
  • Took me some time to find the place where I was able to test that current implementation. The dates seem to be treated as strings and not dates. I was looking already through several threads to figure out if the column is date or not. If we would use lodash as is, it sorts correctly, but we need strings to be sorted case-insensitive. I hoped for some simple way to fix it. – Naomi May 31 '18 at 15:17
  • 1
    What does "handle dates properly" mean then? They can't be sorted properly if they are strings (depends on the format), but lowercasing them shouldn't hurt anything. – FINDarkside May 31 '18 at 15:24
  • They are sorted as strings and not as dates and they are actual dates. You see that we added a special case for numeric using ParseFloat, but I think we need a special case for dates as well. And so here I see two problems - first how to determine if the column is date or not and secondly what to use in that function. – Naomi May 31 '18 at 15:29
  • May be I was not very clear in my question - the above method is a generic method in our TypedArrayFactory. So, we need some generic method which will work with array of objects with columns of different types. It should sort columns according to the type and sort character columns case-insensitive. – Naomi May 31 '18 at 15:33

1 Answers1

1

_.sortBy can sort dates - assuming all the values in the column are dates, you only need to test the type and return the date:

const sorted = _.orderBy(this, function(o) {
  if ($.isNumeric(o[column])) {
    return parseFloat(o[column]);
  }

  if (_.isDate(o[column])) {
    return o[column];
  }

  return (o[column]).toLowerCase();
}, direction);
ic3b3rg
  • 14,629
  • 4
  • 30
  • 53
  • I've tried that yesterday and it didn't work for me. I think originally I got datetimes, but this is what I actually put in the final result: val[i].dateTime = moment(val[i].dateTime).format("MM/DD/YYYY HH:mm:ss"); form.accessRecords.push(val[i]); Do you think because of moment.format my dates became string? Is there still a way to make it work generically even for this case (assuming dates were converted to strings)? – Naomi Jun 01 '18 at 12:08
  • We'll need to investigate if it would be possible to add filter (formatting) directly to the control (directive) we're using for displaying the results so I would not need to transform the data. – Naomi Jun 01 '18 at 12:12
  • 1
    Yes, `moment.format` does convert date to string. You can't sort dates correctly in that format, but if you change the format to `YYYY/MM/DD HH:mm:ss`, it will work. If you need the other format, you should sort first (as date) and then format. – ic3b3rg Jun 01 '18 at 18:00
  • I added a request to our team to implement ability to add filter in the directive we use for displaying results. This way we'll be able to keep date as date and still format it properly. I tested the solution now without changing the date (so it's currently displayed in not user friendly format) and it works fine. I'll mark the answer and we have a plan to enhance our directive. – Naomi Jun 01 '18 at 18:26