Sorting array elements by date

来源:互联网 发布:淘宝元素运动是正品吗 编辑:程序博客网 时间:2024/05/21 16:23

I have the following array.

dates = ["6/23/2014", "8/5/2014", "8/19/2014", "6/26/2014", "8/19/2014", "8/19/2014","7/8/2014", "6/3/2014", "7/30/2014", "7/3/2014", "6/3/2014", "6/26/2014"]

Our array stores 10 string objects. In order to sort them my way, I need to re-arrange each element.

"2014/8/5", "2014/8/19", "2014/8/19", etc.

I don't know why your expected output contains only 9 out of 12 entries, and that you mention an array of size 10, but I believe your want to sort all 12. My preference would be to do it the way @BroiSatse has, but I will offer a way that does not use methods from the class Date. I include it because it has some interesting aspects for those new to Ruby.

dates = ["6/23/2014", "8/5/2014",  "8/19/2014", "6/26/2014",         "8/19/2014", "8/19/2014", "7/8/2014",  "6/3/2014",         "7/30/2014", "7/3/2014",  "6/3/2014",  "6/26/2014"]dates.sort_by { |d| d.split(?/).rotate(-1).map { |e| -e.to_i } }  #=> ["8/19/2014", "8/19/2014", "8/19/2014", "8/5/2014",  #    "7/30/2014", "7/8/2014",  "7/3/2014",  "6/26/2014",  #    "6/26/2014", "6/23/2014", "6/3/2014", "6/3/2014"]

Here's what's happening.

enum = dates.sort_by  #=> #<Enumerator: ["6/23/2014", "8/5/2014",  "8/19/2014", "6/26/2014",  #                  "8/19/2014", "8/19/2014", "7/8/2014",  "6/3/2014",  #                  "7/30/2014", "7/3/2014",  "6/3/2014",  "6/26/2014"]:sort_by>

As you see, enum is an enumerator. The first value that it passes into its block is "6/23/2014", which it assigns to the block variable:

d = "6/23/2014"a = d.split(?/)  #=> ["6", "23", "2014"]b = a.rotate(-1)  #=> ["2014", "6", "23"]c = b.map { |e| -e.to_i }  #=> [-2014, -6, -23]

Similarly, the third element of enum is converted to:

"8/19/2014".split(?/).rotate(-1).map { |e| -e.to_i }  #=> [-2014, -8, -19]

sort_by uses Array#<=> to compare pairs of elements. After reading that doc you'll understand why:

[-2014, -6, -23] <=> [-2014, -8, -19]  #=> 1

meaning that "8/19/2014" should precede "6/23/2014" in the sort.

Incidentally, it was necessary to convert months and days from strings to integers because those strings did not contain leading zeros for single-digit values. If we had left them as strings, "8" > "15", which is not what we want. Since we are converting to integers anyway, it was easier to make them negative than to leave them positive and apply reverse to the sorted array.

 

Try:

dates.sort_by {|s| Date.strptime(s, '%m/%d/%Y')}

If you want it starting from the newest date:

dates.sort_by {|s| Date.strptime(s, '%m/%d/%Y')}.reverse

 

0 0