排序难度

时间:2015-12-03 20:26:34

标签: ruby-on-rails ruby algorithm sorting

我有一堆对象,我们称之为Items,每个Item都有weightpublisher。我希望按weight(递减)对它们进行排序,但是,这是一个棘手的问题,确保没有Items具有相同publisher的{​​{1}}出现两次(或更多)一排。

我在考虑使用sort_by循环并跟踪发布商索引(使用发布者作为键和索引数组作为值的哈希),但我不是如果这是最好的方法,那么确定这是最好的方法,或者如何在实践中处理这个问题。有什么建议吗?

EX:

说所有这些项目都在一个名为items的数组中并随机排序。我想对它们进行排序,以便首先显示重量= 2个项目,并且使用“foo”#39;因为如果可能的话,发布商不会彼此相邻(如果该重量级别中没有其他发布者,则他们会彼此相邻)

items = [(id: 1, name: "item1", publisher: "foo", weight: 2),
    (id: 2, name: "item2", publisher: "foo", weight: 2),
    (id: 3, name: "item3", publisher: "baz", weight: 1),
    (id: 4, name: "item4", publisher: "bar", weight: 2)]

puts custom_sorting_method(items)

将返回

   [(id: 1, name: "item1", publisher: "foo", weight: 2),
    (id: 4, name: "item4", publisher: "bar", weight: 2),
    (id: 2, name: "item2", publisher: "foo", weight: 2),
    (id: 3, name: "item3", publisher: "baz", weight: 1)]

3 个答案:

答案 0 :(得分:2)

您可以尝试按权重分组并按发布者对每个分组列表进行排序,然后选择每个排序列表的第一个和最后一个元素。非常粗略:

results = []
alt_methods = [:shift, :pop]

grouped = items.group_by{ |item| item[:weight] }
grouped_and_sorted = grouped.each do |k,v|
  v.sort_by { |item| item[:publisher] }
end

grouped_and_sorted.each do |k,v|
  v.length.times{ |i| results << v.send(alt_methods[i%2]) }
end

答案 1 :(得分:1)

sorted = Items.sort{|x,y| y.weight <=> x.weight}
sorted.uniq!{|x| x.publisher}

答案 2 :(得分:1)

# Sorts by weight, and then distributes by publisher within each weight.
#
# @param [Array<Hash>] items
# @return [Array<Hash>]
def special_sort(items)
  by_weight_nested = Hash[
    items
      .group_by { |item| item[:weight] }
      .map { |weight, arr| [weight, arr.group_by { |item| item[:publisher] }] }
  ]

  sorted = []

  by_weight_nested.keys.sort.reverse.each do |weight|
    publishers = by_weight_nested[weight].keys
    0.upto(by_weight_nested[weight].values.map(&:size).max - 1) do |i|
      publishers.each do |publisher|
        sorted << by_weight_nested[weight][publisher][i]
      end
    end
  end

  sorted.compact
end