2

I have a two dimensional array which has following structure

array = [
          ["2019-03-11","00986587","LBP"],
          ["2019-02-23","00462421","USD"],
          ["2019-05-26","00357853","EUR"],
          ["2019-09-15","00357382","LBP"]
        ]

I want to sort the array based on the date (first element of each row).

Looking for the following result:

array = [
          ["2019-09-15","00357382","LBP"],
          ["2019-05-26","00357853","EUR"],
          ["2019-03-11","00986587","LBP"],
          ["2019-02-23","00462421","USD"]
        ]

After my research on sort and sort_by i didn't find any solution. Can anyone please help me to solve my problem ? and thank you

iamzouz
  • 99
  • 1
  • 3
  • 11

3 Answers3

5

You can sort 2d arrays with sort_by method: sort_by sorts in ascending order by default. If you want it to be in descending order, just reverse the result.

array.sort_by{ |a| a.first }.reverse
demir
  • 4,591
  • 2
  • 22
  • 30
2

Two important notes:

  • your dates are written in YYYY-MM-DD format, so sorting them alphabetically will also sort them chronologically.
  • your dates are the first element in the arrays, and array are sorted by their first element first.

It means that all you need is:

array.sort.reverse
#=> => [["2019-09-15", "00357382", "LBP"], ["2019-05-26", "00357853", "EUR"], ["2019-03-11", "00986587", "LBP"], ["2019-02-23", "00462421", "USD"]]

If you want to save modify array in place, you can write:

array.sort!.reverse!
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
1

I suggest to convert the string to a Date object and use it for sorting:

Date.strptime("2019-09-15", '%Y-%m-%d').class
#=> Sun, 15 Sep 2019

See Rails ActiveSupport Time Parsing?


So, if you want to change the original array, use Array#sort!, note the bang (!):
array.sort! { |(date_1, *rest_1), (date_2, *rest_2)| Date.strptime(date_2, '%Y-%m-%d') <=> Date.strptime(date_1, '%Y-%m-%d') }
array
#=> [["2019-09-15", "00357382", "LBP"], ["2019-05-26", "00357853", "EUR"], ["2019-03-11", "00986587", "LBP"], ["2019-02-23", "00462421", "USD"]]

Change the block for inverse order:

Date.strptime(date_1, '%Y-%m-%d') <=> Date.strptime(date_2, '%Y-%m-%d')


Note that for the block variables I used the *splat operator which works like this:
ary = [1,2,3]
a, *b = ary
p a, b
# 1
# [2, 3]
iGian
  • 11,023
  • 3
  • 21
  • 36