ruby数组中的自定义排序

时间:2013-01-22 11:35:36

标签: ruby-on-rails ruby

我有一个非常具体的要求。有三个或四个衬垫解决方案。我需要一个班轮解决方案。

让我们说我有一个类似的数组:

[["Andorra", "Andorra"], ["United Arab Emirates", "United Arab Emirates"], 
 ["Afghanistan", "Afghanistan"], ["Antigua & Barbuda", "Antigua & Barbuda"], 
 ["Anguilla", "Anguilla"], ["Albania", "Albania"], ["Armenia", "Armenia"], 
 ["Angola", "Angola"]]

我希望["安圭拉","安圭拉"]作为我的第一个元素,另一个按降序排列。

有没有办法实现这个目标? (如果可能,一个班轮)

4 个答案:

答案 0 :(得分:6)

利用数组定义的词典顺序,并按所需条件对输入进行排序:

countries.sort_by { |s, s2| [s == "Anguilla" ? 1 : 0, s] }.reverse
#=> [["Anguilla", "Anguilla"], ..., ["Afghanistan", "Afghanistan"]]

@Sergio建议使用Enumerable#sort来避免reverse。 IMO它的声明性比前者要少,但是对于记录来说,这就是它的外观:

countries.sort { |(s1, _), (s2, _)| s1 == "Anguilla" ? -1 : s2 <=> s1 }
#=> [["Anguilla", "Anguilla"], ..., ["Afghanistan", "Afghanistan"]]

答案 1 :(得分:4)

这是你的单行:

countries = [["Andorra", "Andorra"], ["United Arab Emirates", "United Arab Emirates"], ["Afghanistan", "Afghanistan"], ["Antigua & Barbuda", "Antigua & Barbuda"], ["Anguilla", "Anguilla"], ["Albania", "Albania"], ["Armenia", "Armenia"], ["Angola", "Angola"]]

custom_order = countries.partition{|arr| arr[0] == "Anguilla"}.map(&:sort).map(&:reverse).flatten(1)
custom_order # => [["Anguilla", "Anguilla"], ["United Arab Emirates", "United Arab Emirates"], ["Armenia", "Armenia"], ["Antigua & Barbuda", "Antigua & Barbuda"], ["Angola", "Angola"], ["Andorra", "Andorra"], ["Albania", "Albania"], ["Afghanistan", "Afghanistan"]]

这是另一种解决方案:

custom_order = countries.sort do |c1, c2|
  if c1[0] == 'Anguilla'
    -1
  else
    c2 <=> c1
  end
end

答案 2 :(得分:0)

有点原始,但有一行:

[["Anguilla", "Anguilla"]] << ([["Andorra", "Andorra"], ["United Arab Emirates", "United Arab Emirates"], ["Afghanistan", "Afghanistan"], ["Antigua & Barbuda", "Antigua & Barbuda"], ["Anguilla", "Anguilla"], ["Albania", "Albania"], ["Armenia", "Armenia"], ["Angola", "Angola"]] - ["Anguilla", "Anguilla"]).sort{|a,b| b[0] <=> a[0]}

答案 3 :(得分:0)

试试这个:

[["Andorra", "Andorra"], ["United Arab Emirates", "United Arab Emirates"], ["Afghanistan", "Afghanistan"], ["Antigua & Barbuda", "Antigua & Barbuda"], ["Anguilla", "Anguilla"], ["Albania", "Albania"], ["Armenia", "Armenia"], ["Angola", "Angola"]].sort{|a,b| b[0] <=> a[0]}.partition{|arr| arr[0] == "Anguilla"}