我有一组Line
个对象。每行都有一个row_number
属性,它是一个整数:
Line.row_number = 1,
Line.row_number = 2,
Line.row_number = 3,
Line.row_number = 5,
Line.row_number = 6,
Line.row_number = 20,
Line.row_number = 24,
Line.row_number = 25,
Line.row_number = 0
我想创建一个哈希,其键是整数,值是连续row_numbers
的所有行。我希望哈希看起来像这样:
0 =>
Line.row_number = 0,
Line.row_number = 1,
Line.row_number = 2,
Line.row_number = 3,
Line.row_number = 5,
Line.row_number = 6,
1 =>
Line.row_number = 20
2 =>
Line.row_number = 24,
Line.row_number = 25,
有人可以让我知道我可以用哪种算法来实现这个目标吗?
答案 0 :(得分:2)
您可以对数组进行排序,然后迭代它。如果当前元素不等于前一个元素+1
,则启动新组。
答案 1 :(得分:1)
您在问题中提供的示例不是有效的Ruby代码,因此很难理解您要执行的操作。我假设你的目标的本质是转换一个数组:
[1,2,24,3,5,6,20,25,0]
到一个看起来像这样的哈希:
{ 0=>[0,1,2,3], 1=>[5,6], 2=>[20], 3=>[24,25] }
<强>代码强>
def hashify(arr)
a = arr.sort
curr_val = a.first
a.slice_before do |i|
last_val = curr_val
curr_val = i
last_val + 1 < curr_val
end.with_index.with_object({}) { |(arr,j),h| h[j]=arr }
end
示例强>
hashify [1,2,24,3,5,6,20,25,0]
#=> {0=>[0, 1, 2, 3], 1=>[5, 6], 2=>[20], 3=>[24, 25]}
<强>解释强>
arr = [1,2,24,3,5,6,20,25,0]
a = arr.sort
#=> [0, 1, 2, 3, 5, 6, 20, 24, 25]
curr_val = a.first
#=> 0
enum0 = a.slice_before do |i|
last_val = curr_val
curr_val = i
last_val + 1 < curr_val
end
#=> #<Enumerator: #<Enumerator::Generator:0x0000010109aea0>:each>
enum0.to_a
#=> [[0, 1, 2, 3], [5, 6], [20], [24, 25]]
enum1 = enum0.with_index
#=> #<Enumerator: #<Enumerator: \
# #<Enumerator::Generator:0x0000010109aea0>:each>:with_index>
enum1.to_a
#=> [[[0, 1, 2, 3], 0], [[5, 6], 1], [[20], 2], [[24, 25], 3]]
enum2 = enum1.with_object({})
#=> #<Enumerator: #<Enumerator: #<Enumerator: \
# #<Enumerator::Generator:0x0000010109aea0>:each>:with_index>:with_object({})>
enum2.to_a
#=> [[[[0, 1, 2, 3], 0], {}], [[[5, 6], 1], {}], [[[20], 2], {}], [[[24, 25], 3], {}]]
enum2.each { |(a,j),h| h[j]=a }
#=> {0=>[0, 1, 2, 3], 1=>[5, 6], 2=>[20], 3=>[24, 25]}
enum0
,enum1
,enum2
都是枚举者。您可以将后两者视为“复合”枚举器。 enum0.to_a
显示值enum0
将传递到其块(如果有的话)。 enum1.to_a
和enum2.to_a
相同(后者确实有一个块)。
考虑最后一步。 enum2
传递到块中的each
的第一个值是[[0,1,2,3],0],{}]
。这些分配给块变量如下:
a => [0, 1, 2, 3]
j => 0
h => {}
和
h[0] = [0, 1, 2, 3]
已执行,因此哈希现在是:
h #=> {0=>[0, 1, 2, 3]}
each
传递给块的第二个值将以下值分配给块变量:
a = [5, 6]
j = 1
h = {0=>[0, 1, 2, 3]}
和
h[1] = [5, 6]
执行,结果是:
h #=> {0=>[0, 1, 2, 3], 1=>[5, 6]}
each
将剩余的两个值传递给块,并执行simliar计算,然后枚举器返回h
。
答案 2 :(得分:-1)
使用array.sort_by(&:row_number).group_by{ |e| e.row_number.div(10) }
:
> Line = Struct.new(:row_number)
> t = 0.upto(20).each.map{ |i| Line.new(i) }.shuffle
> t.sort_by(&:row_number).group_by{ |e| e.row_number.div(10) }
=> {0=>[#<struct Line row_number=0>, #<struct Line row_number=1>, #<struct Line row_number=2>, #<struct Line row_number=3>, #<struct Line row_number=4>, #<struct Line row_number=5>, #<struct Line row_number=6>, #<struct Line row_number=7>, #<struct Line row_number=8>, #<struct Line row_number=9>],
1=>[#<struct Line row_number=10>, #<struct Line row_number=11>, #<struct Line row_number=12>, #<struct Line row_number=13>, #<struct Line row_number=14>, #<struct Line row_number=15>, #<struct Line row_number=16>, #<struct Line row_number=17>, #<struct Line row_number=18>, #<struct Line row_number=19>],
2=>[#<struct Line row_number=20>]}