【问题标题】:Sort array of arrays that is a value of a hash对作为哈希值的数组的数组进行排序
【发布时间】:2017-08-26 01:49:49
【问题描述】:

我看到了几篇关于对作为哈希值的数组进行排序的帖子,但我正在尝试对作为哈希值的数组数组进行排序。 我有一个看起来像这样的哈希:

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

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

【问题讨论】:

    标签: arrays ruby sorting hash


    【解决方案1】:

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

    h.map { |k, v| [k, v.sort_by(&:first)] }.to_h
    

    【讨论】:

      【解决方案2】:
      h.merge(h) { |*, n| n.sort }
        #=> {"pets"=>[["cat", 2], ["dog", 1]], "fruits"=>[["apple", 2], ["orange", 1]]}
      

      这不会修改h

      这使用Hash#merge 的形式,它使用一个块来确定在被合并的两个散列中存在的键的值,这里是所有键。该块具有三个块变量,公共密钥kk 的值用于“旧哈希”ok 的值用于“新”哈希n。(这里@ 987654329@ 和n 当然是相等的。)我只使用这些变量中的最后一个,所以我将块变量表示为|*, 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
      

      【讨论】:

      • 出色的merge 使用情况,Cary。谢谢,我真的很喜欢看到这个。在后一个示例中,h[k].sort! 应该足够了。
      • 轻微的挑剔,你可以使用each_key 来代替keys.each,这可能只是一种风格偏好,但这是一回事,还有each_value,因为你正在就地排序
      • 好点,@SimpleLime,但我决定删除该行并坚持使用不会改变哈希的解决方案。在我的替代品中,我发现我可以使用 each_keyEnumerable#zip
      【解决方案3】:

      我看到的一个问题是您正在尝试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 个参数(xy)时,您正在使用数组(并且因为Ruby 处理元组的方式),这些参数已设置到数组的第一个和第二个值。 (x == "dog", y == 1)

      所以这里有 2 个选项:保持块不变并将可枚举方法切换到 sort,或切换到 sort_by 并更改块:

      sort:

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

      sort_by:

      h.each { |key, value| h[key] = value.sort_by! { |x, y| y } } # In this case, `y` is the second value in your arrays, which is the integer
      

      【讨论】:

      • 只需在Hash#map 返回的数组上调用to_h 即可取回哈希。
      猜你喜欢
      • 1970-01-01
      • 2020-04-05
      • 2011-05-22
      • 2015-04-08
      • 1970-01-01
      • 2017-12-13
      • 2019-04-25
      • 1970-01-01
      • 2011-03-10
      相关资源
      最近更新 更多