【问题标题】:Sorting an array of hashes with the smallest value in the middle对中间值最小的哈希数组进行排序
【发布时间】:2020-01-22 17:28:03
【问题描述】:

我是 ruby​​ 新手,没有找到任何关于如何做到这一点的答案或逻辑。我正在尝试将一个数组分成两半,其中一半以降序排序,另一半以升序排序。

长话短说,假设我们有以下哈希数组:

[
 {:rating=>1, :num=>1},
 {:rating=>1, :num=>1},
 {:rating=>3.5, :num=>37},
 {:rating=>4.0, :num=>23},
 {:rating=>4.0, :num=>72},
 {:rating=>4.0, :num=>38}, 
 {:rating=>3.5, :num=>72}, 
 {:rating=>4.0, :num=>74}
]

我不太擅长解释事情,但我会尽力更好地解释预期的结果。

首先,我需要获取具有最小:rating 键值和:num 键值的散列并将其推送到新数组中。剩余的散列应该在:rating:num 之后按升序排序,然后每个散列,从具有最小:rating 值的散列开始,应该按照以下规则推入新创建的数组中:one in数组的开头和结尾,直到没有哈希值。

所以最终的结果应该是这样的:

[
 {:rating=>4.0, :num=>74},
 {:rating=>4.0, :num=>72},
 {:rating=>3.5, :num=>72},
 {:rating=>1, :num=>1},
 {:rating=>1, :num=>1},
 {:rating=>3.5, :num=>37},
 {:rating=>4.0, :num=>23},
 {:rating=>4.0, :num=>38}
]

非常感谢任何帮助。谢谢。

【问题讨论】:

  • 上半场是什么意思?
  • 您选择的答案返回的排序与您想要的“最终结果”有很大不同。你这样做的理由是什么?
  • 我对你的问题投了反对票,因为它不清楚。具体来说,在对两部分进行排序之前对数组进行分区的标准是什么?如果您通过编辑澄清来解决@iGian 的评论(我不相信您已经看到),我将删除我的反对票。

标签: arrays ruby sorting hash


【解决方案1】:

可能有点复杂的解决方案,但它的工作原理。请看一下,我会尝试重构它

initial_array = [
    {:rating=>1, :num=>1},
    {:rating=>1, :num=>1},
    {:rating=>3.5, :num=>37},
    {:rating=>4.0, :num=>23},
    {:rating=>4.0, :num=>72},
    {:rating=>4.0, :num=>38},
    {:rating=>3.5, :num=>72},
    {:rating=>4.0, :num=>74}
]


length = initial_array.length
new_array = []

length.times do |i|
  is_odd = i % 2 == 1
  min_index = initial_array.map{|el| el[:rating]}.each_with_index.min.last
  if is_odd
    new_array.push(initial_array.delete_at(min_index))
  else
    new_array.unshift(initial_array.delete_at(min_index))
  end
end

p new_array

主要思想是每次从数组中找到最小元素,然后从右到左一次将其推送到新数组。

通过评级 (map{|el| el[:rating]}) 找到最小值,但是您可以实现一些更复杂的功能,根据您的业务逻辑同时使用 ratingnum

【讨论】:

  • 这会返回 [{:rating=>4.0, :num=>38}, {:rating=>4.0, :num=>23}, {:rating=>3.5, :num=>37}, {:rating=>1, :num=>1}, {:rating=>1, :num=>1}, {:rating=>3.5, :num=>72}, {:rating=>4.0, :num=>72}, {:rating=>4.0, :num=>74}],这与 OP 想要的“最终结果”几乎没有相似之处。
  • 其实我的回答是遵循大体思路——中间最小,向结尾逐步增加。如果您想获得与问题完全相同的答案,只需将is_odd 决心更改为is_odd = i % 2 == 0
【解决方案2】:

对于“将数组一分为二”,我能想到的唯一解释与您想要的结果一致,即要按升序排序的哈希是那些 h 的哈希 h[:num] 是小于数组中所有哈希 h 的值 h[:num] 的平均值,并且剩余的哈希将按升序排序。

假设这个解释是正确的,并且让变量arr 持有你的数组,可以得到想要的排序数组,如下所示。

avg = arr.sum { |h| h[:num] }.fdiv(arr.size)
  #=> 39.75

arr.sort_by { |h| h[:num] < avg ? [h[:rating], h[:num]] : [-h[:rating], -h[:num]] }
  #=> [{:rating=>4.0, :num=>74},
  #    {:rating=>4.0, :num=>72},
  #    {:rating=>3.5, :num=>72},
  #    {:rating=>1,   :num=> 1},
  #    {:rating=>1,   :num=> 1},
  #    {:rating=>3.5, :num=>37},
  #    {:rating=>4.0, :num=>23},
  #    {:rating=>4.0, :num=>38}] 

【讨论】:

  • 有趣的方法。这也很好用。谢谢!
  • 我在第一段中的解释是否正确?无论如何,您需要编辑您的问题以阐明“将数组一分为二”。
猜你喜欢
  • 2011-03-10
  • 1970-01-01
  • 2020-04-05
  • 2019-04-25
  • 2015-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
相关资源
最近更新 更多