抱歉,如果之前有人问过这个问题,我什至不确定如何搜索它,而且我搜索的内容没有产生任何有用的答案。
这是我的问题,我有一个框架,基本上管理将提交给 PBS 集群的作业,每个作业都需要从输入文件中读取。我们的情况是,我们有超过 5k 个作业需要运行,并且有批处理,比方说,大约 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/