在其他散列中按值对哈希进行排序 - Ruby on Rails

时间:2014-05-14 19:40:04

标签: ruby-on-rails ruby sorting hash

我有一个包含内部另一个哈希的哈希,我需要排序如下:

data = {
    "user": {
        "name": "John",
        "age": "36",
    },
    "company": "Terminal",
    "country": "Canada",
} 
{
    "user": {
        "name": "Mary",
        "age": "32",
    },
    "company": "Brasco",
    "country": "Italy",
}

使用这种方式我可以毫无问题地排序:

data.sort_by { |a| [a[:company], a[:country]] }

但是如果“公司”和“国家”具有相同的价值,我需要按第三个选项“名称”排序。

案例是我需要在结尾处使用“反向”功能(我发布的示例不是真实的情况,真正的那个太大了......哈哈)。

因此,结果也是对名称进行了反转。

data.sort_by { |a| [a['company'], a['country'], a['user']['name']] }.reverse

我需要在DESC中使用“company”和“country”排序,并在ASC中按user.name排序。

3 个答案:

答案 0 :(得分:2)

data.sort_by { |a| [a['company'], a['country'], a['user']['name']] }

sort_by收到一个数组时,它会比较前一个数据时的每个元素。

如果您想对company ASC, country ASC, name ASC进行排序,然后轻松将其反转为company DESC, country DESC, name ASC,您可以这样做:

sorted = data.group_by do |x| 
  [x['company'], x['country']] 
end.each do |k, v| 
  v.sort_by! { |x| x[:user][:name] } 
end.sort_by(&:first).map(&:last)

这将创建一个数组数组,每个内部数组包含公司/国家/地区对中的所有用户,按名称排序。

现在要获得ASC选项:

sorted.flatten

和反向(用户仍然是ASC)你需要:

sorted.reverse.flatten

答案 1 :(得分:0)

这个怎么样

data = [
{
 "user" => {
    "name" => 'John',
    "age" => "36",
  },
  "company" => "Terminal"
  "country" => "Canada"
},
{
"user" => {
    "name" => 'Mary',
    "age" => "32",
  },
  "company" => "Brasco",
  "country" => "Italy"
},
{
"user" => {
    "name" => 'Andre',
    "age" => "32",
  },
  "company" => "Brasco",
  "country" => "Italy"
}]


data.sort do |a,b| 
  sort_direction = [a['company'],a['country']] <=> [b['company'],b['country']]
  b['user']['name'] <=> a['user']['name'] if sort_direction == 0
end
#=>=> [{"user"=>{"name"=>"Mary", "age"=>"32"}, "company"=>"Brasco", "country"=>"Italy"}{"user"=>{"name"=>"Andre", "age"=>"32"},"company"=>"Brasco", "country"=>"Italy"},{"user"=>{"name"=>"John", "age"=>"36"}, "company"=>"Terminal","country"=>"Canada"}]

答案 2 :(得分:0)

如果经常这样做可能的方法:

class Reverser
  attr_reader :v

  def initialize(v)
    @v = v
  end

  def self.[](v)
    new(v)
  end

  def <=>(other)
    other.v <=> @v
  end
end

# Order by company DESC, country DESC, user.name ASC
data.sort_by { |a| [Reverser[a['company']], Reverser[a['country']], a['user']['name']] }