如何通过设置关键元素的优先级来使用字符串键对ruby哈希进行排序?

Eva*_*oss 1 ruby sorting ruby-on-rails

我有一个包含以下值的哈希:

hash = {
  'red': { something: ''},
  'green': { something: '' },
  'yellow': { something: ''}
}
Run Code Online (Sandbox Code Playgroud)

做这样的事情最简单的方法是什么:

hash.sort_by_key_with_priority(['green', 'yellow', 'red'])
Run Code Online (Sandbox Code Playgroud)

并返回:

hash = {
  'green': { something: '' },
  'yellow': { something: ''},
  'red': { something: ''},
}
Run Code Online (Sandbox Code Playgroud)

Ser*_*sev 7

如果优先级数组包含所有哈希键,则不需要排序.您可以简单地将哈希分开并构建一个新哈希.

hash = {
  red: { something: ''},
  green: { something: '' },
  yellow: { something: ''}
}

priority = %i[green yellow red]

hash.slice(*priority)
# => {:green=>{:something=>""}, :yellow=>{:something=>""}, :red=>{:something=>""}}
Run Code Online (Sandbox Code Playgroud)


Sun*_*eep 5

如果哈希中的键未包含在优先级数组中:

>> h = {red: 512, green: 63, yellow: 99, foo: 42, baz: 'hi'}
=> {:red=>512, :green=>63, :yellow=>99, :foo=>42, :baz=>"hi"}
>> p = %i[green yellow red]
=> [:green, :yellow, :red]

# this puts keys not in array at start
# h.sort_by { |k, v| p.include?(k) ? p.index(k) : -1 }
>> h.sort_by { |k, v| p.index(k) || -1 }
=> [[:foo, 42], [:baz, "hi"], [:green, 63], [:yellow, 99], [:red, 512]]

# this puts keys not in array at end
# h.sort_by { |k, v| p.include?(k) ? p.index(k) : p.size }
>> h.sort_by { |k, v| p.index(k) || p.size }
=> [[:green, 63], [:yellow, 99], [:red, 512], [:foo, 42], [:baz, "hi"]]
Run Code Online (Sandbox Code Playgroud)

对结果使用to_h方法来转换为hash

  • 您还可以使用上面提供的方法,例如“Hash#slice”与“Hash#merge”结合使用,例如“h.slice(*p).merge(h) {|_,o,_|” o}`。如果元素不存在,`Array#index`也会返回nil,所以`p.index(k) || -1` 消除了对三元的需要以及两次遍历 `Array` 的需要 (2认同)