对数组的数组进行排序,该数组是哈希值

时间:2017-08-26 01:49:50

标签: arrays ruby sorting hash

我看到有几个关于排序数组的帖子,这是一个散列值,但我试图对一个数组数组进行排序,这是一个散列值。 我有一个看起来像这样的哈希:

h = { 
      "pets"=>[["dog", 1], ["cat", 2]],
      "fruits"=>[["orange", 1], ["apple", 2]]
     }

我想根据里面数组的第一个元素(字符串)对数组进行排序。 所以我希望结果是

{ 
  "pets"=>[["cat", 2], ["dog", 1]],
  "fruits"=>[["apple", 2], ["orange", 1]]
}

这就是我现在所拥有的:

h.map do |key, value|
  value.sort_by! { |x, y| x[0] <=> y[0] }
end

但这只是返回原始数组。我需要改变什么? 谢谢!

3 个答案:

答案 0 :(得分:3)

h.merge(h) { |*, n| n.sort }
  #=> {"pets"=>[["cat", 2], ["dog", 1]], "fruits"=>[["apple", 2], ["orange", 1]]}

这不会修改h

这使用Hash#merge的形式,它使用一个块来确定合并的两个哈希中存在的键的值,这里是所有键。该块有三个块变量,公共密钥k,&#34;旧哈希的k值,o和&k的值#34;新&#34;哈希,n。 (此处on当然是相同的。)我只使用最后一个变量,因此我将块变量表示为|*, n|,而不是比|k, o, n|。有关详细信息,请参阅文档。

另一种不会改变h的方式:

h.each_key.zip(h.each_value.map(&:sort)).to_h
  #=> {"pets"=>[["cat", 2], ["dog", 1]], "fruits"=>[["apple", 2], ["orange", 1]]}

这可以写成

h.keys.zip(h.values.map(&:sort)).to_h

答案 1 :(得分:3)

不可变版本,没有副作用:

<dict>
    <key>scope</key>
    <string>support.type.property-name.css</string>
    <key>settings</key>
    <dict>
        <key>foreground</key>
        <string>#FFB6C1</string>
    </dict>
</dict>

答案 2 :(得分:1)

我看到的一个问题是你试图map你的哈希。这将始终返回一个数组。

在这种情况下,你会得到这样的东西: [[["cat", 2], ["dog", 1]], [["apple", 2], ["orange", 1]]]

如果要修改哈希值,可以执行以下操作:

h.each { |key, value| h[key] = value.sort_by { ... } }

然后h将成为新哈希,按您的预期排序。 或者您可以将其设置为另一个变量:

new_hash = h.each { |key, value| value.sort_by! { ... } }

接下来,看起来您已经混淆了sortsort_by。 (容易做到) 使用sort时,您在块中传递的两个变量将分配给要比较的值。 (在你的例子中,数组["dog", 1]是一个参数,另一个是另一个数组来比较它,比如["cat", 2]) 但是,sort_by希望您进行计算以确定它在新订单中的位置。通常sort_by只接受一个参数,但是因为当你告诉sort_by接受2个参数(x和{时,你正在处理数组(并且由于Ruby处理元组的方式) {1}})这些设置为数组的第一个和第二个值。 (yx == "dog"

所以你在这里有2个选项:保持你的阻止相同,并将你的可枚举方法切换到y == 1,或切换到sort并更改你的阻止:

sort_by

sort

h.each { |key, value| h[key] = value.sort! { |x, y| x[0] <=> y[0] } }

sort_by