ruby - 在Ruby中按批处理对数组进行排序

原文 标签 ruby sorting

抱歉,如果以前已经问过这个问题,我不确定该如何搜索,而我搜索的内容却没有任何有用的答案。

这是我的问题,我有一个基本上可以管理将提交到PBS集群的作业的框架,并且每个作业都需要从输入文件中读取。在这种情况下,我们有超过5000个作业需要运行,并且有大约30个批次(例如,从不同的文件读取),而其余的则从另一个作业正在读取的文件中读取。

通过能够按ID对作业列表进行排序,可以很容易地解决该问题(尽管不是最好的解决方案购买可能是我们所拥有的时间范围内最快的解决方案),这基本上意味着它将要读取的文件,即我会喜欢排序这样的数组

a = [1,1,1,2,2,2,3,3,3,4,4,4]

进入
a = [1,2,3,4,1,2,3,4,1,2,3,4]

有没有办法在 ruby 中实现这样的排序?我想起一个算法购买也许已经完成,有人知道答案。

谢谢!

最佳答案

解决方案

感谢@ sagarpandya82的初衷和@Cary Swoveland的错误发现!

可以使用2种方法:

def safe_transpose_and_flatten(array)
  l = array.map(&:length).max
  array.map{|e| e.values_at(0...l)}.transpose.flatten.compact
end

def sort_by_batches(array)
  safe_transpose_and_flatten(array.sort.group_by{|i| i}.values)
end

或这种单行代码(为了便于阅读,分成多行):
def sort_by_batches(array)
  array.group_by{|i| i }.values                  # Chunks of equal values,
       .sort_by{|v| -v.size }                    # sorted by decreasing length,
       .reduce(&:zip)                            # transposed,
       .map{|r| r.flatten.compact.sort }.flatten # flattened and sorted
end

例子
a = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
sort_by_batches(a) # => [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]

a = [1, 1, 3, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 1, 1]
sort_by_batches(a) # => [1, 2, 3, 4, 5, 1, 2, 3, 4, 1, 2, 3, 4, 1, 3]

a = [1,2,2,3,3,3]
sort_by_batches(a) # => [1, 2, 3, 2, 3, 3]

脚步

这是第二个数组的步骤:
[1, 1, 3, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 1, 1] # input
{1=>[1, 1, 1, 1], 3=>[3, 3, 3, 3], 2=>[2, 2, 2], 4=>[4, 4, 4], 5=>[5]} # group_by
[[1, 1, 1, 1], [3, 3, 3, 3], [2, 2, 2], [4, 4, 4], [5]] # values
[[1, 1, 1, 1], [3, 3, 3, 3], [2, 2, 2], [4, 4, 4], [5]] # sort_by -length
[[[[[1, 3], 2], 4], 5], [[[[1, 3], 2], 4], nil], [[[[1, 3], 2], 4], nil], [[[[1, 3], nil], nil], nil]] # zip
[[1, 2, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3, 4], [1, 3]] # map(&:flatten) and compact
[1, 2, 3, 4, 5, 1, 2, 3, 4, 1, 2, 3, 4, 1, 3] # flatten
.reduce(&:zip).map(&:flatten).compact最初被用作安全的转置,但是当第一个数组小于其他数组时,它不起作用。

第一种方法使用this答案进行转置,在使用zip之前,单线通过减小长度来对数组进行排序。

申请工作类别

这是一个非常基本的Job类作为示例:
class Job
  attr_reader :id
  def initialize(id)
    @id = id
  end

  def self.sort_by_batches(jobs)
    safe_transpose_and_flatten(jobs.sort_by{|j| j.id}.group_by{|j| j.id}.values)
  end

  def to_s
    "Job %d" % id
  end
end

jobs = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4].map{|i| Job.new(i)}
Job.sort_by_batches(jobs)

它输出:
Job 1
Job 2
Job 3
Job 4
Job 1
Job 2
Job 3
Job 4
Job 1
Job 2
Job 3
Job 4

关于ruby - 在Ruby中按批处理对数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41231250/

相关文章:

ruby-on-rails - 如何通过 factorygirl 中的特征将属性传递给关联?

ruby-on-rails - 如何使用带密码的 PEM 证书?

javascript - 如何根据值对JavaScript中的对象进行排序?

java - 使用 ArrayList 进行合并排序

postgresql - 按字符列数字排序

ruby - 一切都是 ruby 中的物体吗?

ruby - 提高Ruby中文件搜索的速度

javascript - 从 Controller 函数向选择框添加值(Ruby on Rails)

c - 链表按字母顺序排序,c中的段错误

java - 知道何时以气泡排序结束循环