Order Hash 并删除第一个键值对

Order Hash and delete first key-value pair

我有一个以时间戳为键的散列。

hash = {
  "2016-05-31T22:30:58+02:00" => {
          "path" => "/",
        "method" => "GET"
  },
  "2016-05-31T22:31:23+02:00" => {
          "path" => "/tour",
        "method" => "GET"
  },
  "2016-05-31T22:31:05+02:00" => {
          "path" => "/contact_us",
        "method" => "GET"
  }
}

我订购了这个系列并得到了这样的第一双:

hash.sort_by {|k, _| k}.first.first

但是我该如何删除它呢?

delete 方法requires you 知道键的精确拼写。当然我可以 return 密钥然后在 delete 方法中使用它,但我在想是否有更直接的方法?

您正在寻找的方法是 hash.keys 它 returns 一个键数组:

hash.delete(hash.keys.min)

编辑:我更新了答案以反映必须首先对键进行排序,这已添加到原始问题中并由@Shadwell 在评论中提出post.

我按照@Cary Swoveland 的建议用 hash.keys.sort.first 替换了 hash.keys.min,它不仅性能更高,而且在语义上更好。

另请注意,shift 可用于哈希值。

hash.shift

从散列中删除第一个键值对。也适用于数组。

由于 OP 没有说明散列的键是有序的,我们必须假设不能保证它们是有序的。

hash = { "2016-05-31T22:31:05+02:00"=>{ "path"=>"/tour", "method"=>"GET" },
         "2016-05-31T22:30:58+02:00"=>{ "path"=>"/", "method"=>"GET" },
         "2016-05-31T22:31:23+02:00"=>{ "path"=>"/contact_us", "method"=>"GET" } }

首先,找到最小的键(第二个):

smallest_key = hash.keys.min
  #=> "2016-05-31T22:30:58+02:00" 

这显然比对键排序然后取最小的更有效。

因为日期时间字符串是 iso8601 格式,所以可以将它们作为字符串排序,而不必先将它们转换为 time 对象。

然后使用Hash#reject得到想要的hash:

hash.reject { |k,_| k == smallest_key }
  #=> {"2016-05-31T22:31:05+02:00"=>{"path"=>"/tour", "method"=>"GET"},
  #    "2016-05-31T22:31:23+02:00"=>{"path"=>"/contact_us", "method"=>"GET"}} 

要原地更改 hash,请写

hash.delete(smallest_key }
hash