Ruby: 对数组进行排序,跳过第一个元素

3

我希望按照第一个字符串排序数组的数组,跳过第一个数组,但是我不知道如何使用内置的sort方法来实现。我可以复制整个数组而不包括第一个元素,然后对结果数组进行排序,但是否有更优雅的方式呢?

ar = [["zzzz", "skip", "this"], ["EFP3","eins","eins"], ["EFP10","zwei","zwei"], ["EFP1","drei","drei"]]
ar.sort!{ |a,b|
  if a == ar.first   # why doesn't 
    next             # this
  end                # work ?

  # compare length, otherwise it would be e.g. 10 < 3
  if a[0].length == b[0].length
    a[0] <=> b[0]
  else
    a[0].length <=> b[0].length
  end
}

我希望能够得到这样的结果:
["zzzz", "skip", "this"], ["EFP1","drei","drei"], ["EFP3","eins","eins"], ["EFP10","zwei","zwei"]

"EFP#"排序

编辑:我正在使用Ruby 1.8,如果有关系的话。

5个回答

5
ar[1..-1].sort { whatever you want }

3
你可以这样做:
[ar.first] + ar[1..-1].sort{ |a,b| a[0] <=> b[0] }
# => [["zzzz", "skip", "this"], ["EFP1", "drei", "drei"], ["EFP10", "zwei", "zwei"], ["EFP3", "eins", "eins"]]

3

但是有没有更优雅的方法来做这件事呢?

你可以对其他元素进行排序,然后重新分配它们:

ar = [5, 4, 3, 2, 1]

ar[1..-1] = ar[1..-1].sort

ar #=> [5, 1, 2, 3, 4]

我希望结果能按照"EFP#"排序。

sort_by看起来是正确的工具:

ar = [["zzzz", "skip"], ["EFP3", "eins"], ["EFP10", "zwei"], ["EFP1", "drei"]]

ar[1..-1] = ar[1..-1].sort_by { |s, _| s[/\d+/].to_i }

ar #=> [["zzzz", "skip"], ["EFP1", "drei"], ["EFP3", "eins"], ["EFP10", "zwei"]]

s[/\d+/].to_is中提取数字并将其转换为整数:

"EFP1"[/\d+/].to_i  #=> 1
"EFP3"[/\d+/].to_i  #=> 3
"EFP10"[/\d+/].to_i #=> 10

2
其他人已经解释了如何得出正确的答案。
至于为什么它不起作用,简单来说,sort函数不期望出现“next”。而“next”是一种语言结构,旨在用于普通循环中。然而,作为一个反复请求另一个函数结果的普通Ruby函数,它不能检测到您返回“next”,因为那相当于返回nil(或使函数体为空)。因此,它不能有,也没有任何关于如何处理“next”实例的约定。
它会导致错误,因为nil不是从比较|a,b|返回的有效数字。

0
比较返回-1、0或1,因此如果您为第一个返回1,则它将被排序为第一个元素,如果返回1,则它将成为最后一个元素。
ar.sort!{ |a,b|
  if a == ar.first
    -1
  elsif a[0].length == b[0].length # compare length, otherwise it would be e.g. 10 < 3
    a[0] <=> b[0]
  else
    a[0].length <=> b[0].length
  end
}

#=>[["zzzz", "skip", "this"], ["EFP1", "drei", "drei"], ["EFP3", "eins", "eins"], ["EFP10", "zwei", "zwei"]]

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