根据第一个元素对Ruby二维数组进行排序

4

我有一个二维数组,其结构如下:

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]]

我希望按照第一个元素对数组进行排序,每个数组的第一个元素表示该年中的第几周(例如,“2014年第2周”大于“2013年第50周”)。 结果将会像这样。
["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], 
]

我尝试使用这个。
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}

但这并没有什么帮助。我对Ruby和Rails还很陌生。有没有人能帮我解决问题呢?


如果按原样排序,"2/2014" 应该排在第一位,"7/2013" 应该排在最后,与您的输出不同(忽略您的预期输出根本不是有效的 Ruby 表达式这一事实)。您当前的问题存在矛盾。 - sawa
这不是@sawa所说的。问题提出者似乎希望按照一年中的月份顺序来排列事物。 - paradoja
1
“50/2013” 是一个错误还是 “50” 表示一年中的第几周? - benjaminjosephw
1
谢谢,@benjaminjosephw,它表示一年中的周数。 - Saleh Enam Shohag
@paradoja 这不可能是真的。没有第50个月。你完全错了。 - sawa
@SalehEnamShohag,所有这一切混乱,包括在回答中对您的问题进行错误解读,都是因为您没有充分描述问题。您只提到了“排序”,并没有提到其他任何内容。这意味着应该按字符串排序。您没有提到它应该按整数排序,或者每个项都应转换为数组。这都是您的错。 - sawa
2个回答

10
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]
#]

谢谢。这正是我在寻找的答案。 - Saleh Enam Shohag
挺酷的,但是在 map 方法中 &:to_i 的确切含义是什么? - Liping Huang
2
@LeoHuang &:to_i{ |x| x.to_i } 的一种简写方式。这个链接可以给你更多的了解 https://dev59.com/vHM_5IYBdhLWcg3wzmrL - Santhosh

2
假设你有一个格式正确的第一个元素,也就是说 Date.parse 不会引发任何异常,请使用以下内容:
>> 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) }

为了处理类似于您问题中的50/2013这样格式不正确的日期,您需要决定默认值。假设您想将默认值设置为今天的日期,请将第二行更改为:
>> array.sort_by { |date, _| Date.parse(date) rescue Date.today}

编辑

我原以为第一个元素是日期。但再次查看你的问题后,我认为它不是日期。如果这不是日期的话,我同意sawa的评论。不过,如果你真的想要对其进行排序,可以使用以下方法:

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

编辑 忽略上述的大型方法,使用Santosh的答案。


谢谢。实际上,我指的是2013年的第50周。 - Saleh Enam Shohag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接