Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby two dimensional array sort based on first element

I have a two dimensional array which has following structure

a = [["5/2013", 20.0, 6.0, 6.0], 
["7/2013", 73.0, 66.0, 66.0], 
["50/2013", 11530.0, 12625.27, 12087.75], 
["2/2014", 5926.0, 6058.0, 5876.4], 
["3/2013", 15.0, 0.0, 0.0], 
["4/2013", 15.0, 0.0, 0.0]]

I want to sort the array based on first element, first element of each array presents the week no in year(i.e. "2/2014" means 2nd week in 2014, which is greater than "50/2013") the result will be like this

["3/2013", 15.0, 0.0, 0.0], 
["4/2013", 15.0, 0.0, 0.0],
["5/2013", 20.0, 6.0, 6.0], 
["7/2013", 73.0, 66.0, 66.0], 
["50/2013", 11530.0, 12625.27, 12087.75], 
["2/2014", 5926.0, 6058.0, 5876.4], 
]

I tried with this one

a.sort{|a,b| a[0].split('/')[1].to_i <=> b[0].split('/')[1].to_i  && a[0].split('/')  [0].to_i <=> b[0].split('/')[0].to_i}

but it does not help. I am new in ruby and rails. Can anyone please help me to solve my problem.

like image 500
Saleh Enam Shohag Avatar asked Nov 02 '25 04:11

Saleh Enam Shohag


2 Answers

a.sort_by {|i| i.first.split('/').map(&:to_i).reverse }

#[
#  ["3/2013", 15.0, 0.0, 0.0],
#  ["4/2013", 15.0, 0.0, 0.0],
#  ["5/2013", 20.0, 6.0, 6.0],
#  ["7/2013", 73.0, 66.0, 66.0],
#  ["50/2013", 11530.0, 12625.27, 12087.75],
#  ["2/2014", 5926.0, 6058.0, 5876.4]
#]
like image 111
Santhosh Avatar answered Nov 03 '25 20:11

Santhosh


Assuming you have a properly formed first element, meaning Date.parse will not raise any exception, use the following

>> array = [["5/2013", 20.0, 6.0, 6.0], ["7/2013", 73.0, 66.0, 66.0], ["50/2013", 11530.0, 12625.27, 12087.75], ["2/2014", 5926.0, 6058.0, 5876.4], ["3/2013", 15.0, 0.0, 0.0], ["4/2013", 15.0, 0.0, 0.0]]
>> array.sort_by { |date, _| Date.parse(date) }

To handle improperly formed date like 50/2013 (in your question), you need to decide the default value. Say you want to set the default value to today's date, change the second line to

>> array.sort_by { |date, _| Date.parse(date) rescue Date.today}

EDIT

I assumed that the first element is like a date. Looking at your question a second time leads me to believe that it isn't a date. If this isn't a date, I'll have to agree with sawa's comment. If you really want to sort this though, use the following

array.sort do |a,b|
  num1, year1 = a[0].split('/')
  num2, year2 = b[0].split('/')

  if year1 == year2
    num1.to_i <=> num2.to_i
  else
    year1.to_i <=> year2.to_i
  end
end

EDIT ignore the big method above, use Santosh's answer.

like image 32
jvnill Avatar answered Nov 03 '25 20:11

jvnill



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!