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

时间:2015-07-15 07:16:30

标签: arrays ruby sorting ruby-1.8

我想通过跳过第一个数组的第一个String对字符串数组进行排序,但我不知道如何使用内置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,如果重要的话。

4 个答案:

答案 0 :(得分:2)

你可以这样做:

[ar.first] + ar[1..-1].sort{ |a,b| a[0] <=> b[0] }
# => [["zzzz", "skip", "this"], ["EFP1", "drei", "drei"], ["EFP10", "zwei", "zwei"], ["EFP3", "eins", "eins"]]

答案 1 :(得分:2)

  

但是有没有更优雅的方法来做到这一点?

您可以sort其他元素,然后重新assign

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 :(得分:1)

其他人已经解释了如何得到正确的答案。

至于为什么它不起作用,排序只是不期望“下一步”。 “next”是用于正常循环的语言构造。但是,sort是一个重复询问结果的另一个函数的函数。作为一个普通的Ruby函数,它无法检测你是否返回“next”,因为这相当于返回nil(或将身体留空)。因此,它没有,也没有关于如何处理“下一个”实例的任何约定。

它会导致错误,因为nil不是从| a,b |返回的有效数字比较。

答案 3 :(得分: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"]]