-2

How can I sort "YearMonth" text using Year & Month?

MyArray = ['2019APR', '2019AUG', '2019DEC', '2019FEB', '2019JAN',  
'2019JUL', '2019JUN', '2019MAR', '2019MAY', '2019NOV', '2019OCT',  
'2019SEP', '2020APR', '2020AUG', '2020DEC', '2020FEB', '2020JAN',  
'2020JUL', '2020JUN', '2020MAR', '2020MAY', '2020NOV', '2020OCT', '2020SEP']

Output Require

['2019JAN', '2019FEB', '2019MAR', '2019APR', '2019MAY', '2019JUN',  
'2019JUL', '2019AUG', '2019SEP', '2019OCT', '2019NOV', '2019DEC',  
'2020JAN', '2020FEB', '2020MAR', '2020APR', '2020MAY', '2020JUN',  
'2020JUL', '2020AUG', '2020SEP', '2020OCT', '2020NOV', '2020DEC']

I know Sort() will sort my array in alphabetical order but any optimal custom sort function for this?

I got Answer two Ans

JS I found myself using this way:- https://jsfiddle.net/51u9nb6c/2/

And for .NET c# I mark correct answer

5
  • This is a good place to start: google.co.uk/search?q=jquery+sort+array Commented Oct 30, 2023 at 11:55
  • You will need a sort function that accepts a custom comparison function. This function should split the date string into its components. The year can be converted to a number and used as is. If the year of two compared dates are the same then the function should look at the month string. You can use a pre-defined map/dictionary to get the numeric values of two months and then compare them. Commented Oct 30, 2023 at 12:02
  • 3
    If you're using C# you could also parse the dates with DateTime.ParseExact("2019MAR", "yyyyMMM", System.Globalization.CultureInfo.InvariantCulture) and sort them directly without a custom comparison function. I don't know if JS supports date parsing like that. Commented Oct 30, 2023 at 12:07
  • Please choose either JavaScript or C# for an implementation. Commented Oct 30, 2023 at 12:59
  • Your JS solution looks nice but can be simplified a bit: return a[1] - b[1] || months[a[0]] - months[b[0]]; Commented Oct 30, 2023 at 14:52

2 Answers 2

1

In c#, you can use the Array's Sort overload that takes an Array and a Comparison as arguments:

var arr = new[] { "2019APR", "2019AUG", "2019DEC", "2019FEB", 
                  "2019JAN", "2019JUL", "2019JUN", "2019MAR", 
                  "2019MAY", "2019NOV", "2019OCT", "2019SEP", 
                  "2020APR", "2020AUG", "2020DEC", "2020FEB", 
                  "2020JAN", "2020JUL", "2020JUN", "2020MAR", 
                  "2020MAY", "2020NOV", "2020OCT", "2020SEP" };

Array.Sort(arr, (a, b) => ConvertToDateTime(a).CompareTo(ConvertToDateTime(b)));

private DateTime ConvertToDateTime(string yyyyMMM) 
    => DateTime.ParseExact(
           yyyyMMM, 
           "yyyyMMM", 
           System.Globalization.CultureInfo.InvariantCulture);

Note: You don't have to use the ConvertToDateTime method, it's just a helper to avoid writing the exact same ParseExact call twice.

See a live demo on SharpLab (without the helper method)

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

5 Comments

Would it make a difference (e.g. in high performance scenarios) if ConvertToDateTime was static? (which my VS is suggesting to do)
@Fildor I guess it could make a performance difference, but I seriously doubt that would make a true performance bottle neck. Actually, after writing this comment I went to check and found a Dev.To post claiming static methods are 6 times faster than instance methods, so if it's correct it might make a more significant difference than I thought.
Static vs instance: see this question (and probably others) (though doesn't appear to be any performance tests)
Rather than consider if ConvertToDateTime should be static/not static, if performance is a question, then you would be better off not using any DateTime functions - they are notoriously slow. This is a convenience answer rather than a performant one (not saying it will be slow, just any DateTime Parse function will be slower than a simple split + dictionary lookup) (ie handcode the parsing yourself for performance).
Edit which it appears is what your js solution does - you should add that as its own answer as jsfiddle links may get lost in the future.
1

Simple :

            string[] MyArray = {"2019APR", "2019AUG", "2019DEC", "2019FEB", "2019JAN",
                "2019JUL", "2019JUN", "2019MAR", "2019MAY", "2019NOV", "2019OCT",
                "2019SEP", "2020APR", "2020AUG", "2020DEC", "2020FEB", "2020JAN",
                "2020JUL", "2020JUN", "2020MAR", "2020MAY", "2020NOV", "2020OCT", "2020SEP" };

            string[] sortedArray = MyArray.Select(x => new { s = x, date = DateTime.ParseExact(x, "yyyyMMM", System.Globalization.CultureInfo.InvariantCulture) })
                .OrderBy(x => x.date)
                .Select(x => x.s)
                .ToArray();

3 Comments

Note that this doesn't actually sort the array, but instead returns a new array, sorted as the OP requests. Also, you're creating a new anonymous instance for each item in the array. All in all, this isn't a very memory efficient way to solve the problem, though to be fair it is a valid solution and unless the array is very long or this sort happens a lot of times, it shouldn't be a problem.
@ZoharPeled : Is you method really any different? In your solution is is not obvious what is being done under the hood.
In terms of memory usage, yes. I don't allocate any new reference types. In terms of runtime performance - I believe that if there is any difference, it's negligible.

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.