"a", "2" => "b", "9" => "c", -6ren">
gpt4 book ai didi

ruby-on-rails - 从 ruby 中排列的哈希切片成 block

转载 作者:行者123 更新时间:2023-12-05 08:49:40 26 4
gpt4 key购买 nike

我有散列,其中键按排序顺序排列,散列大小超过 1000。我如何根据范围将散列分成 block 。

示例:-

h_main = {"1" => "a", "2" => "b", "9" => "c", ..............  "880" => "xx", "996" => "xyz", "998" => "lll", "1050" => "mnx"}

我必须根据范围将上面的哈希分成排序器哈希 block :-

h_result = {"1-100" => {"1" => "a", "2" => "b", "9" => "c" ..... "99" => "re"},
"101-200" => {}
....
....

"900-1000" => {"996" => "xyz", "998" => "lll"},
"1000-1100" => {"1050" => "mnx"}
}

我可以通过应用每个循环然后添加条件来合并相应哈希中的键值对,但这是一个漫长的过程。

请帮助提供优化解决方案,在此先感谢。

最佳答案

def doit(h, group_size)
h.keys.
slice_when { |k1,k2| k2.to_i/group_size > k1.to_i/group_size }.
each_with_object({}) do |key_group,g|
start_range = group_size * (key_group.first.to_i/group_size)
g["%d-%d" % [start_range, start_range+group_size-1]] = h.slice(*key_group)
end
end
h = {"11"=>"a", "12"=>"b", "19"=>"c", "28"=>"xx", "29"=> "xyz",
"42"=>"lll", "47"=>"mnx"}
doit(h, 10)
#=> {"10-19"=>{"11"=>"a", "12"=>"b", "19"=>"c"},
# "20-29"=>{"28"=>"xx", "29"=>"xyz"},
# "40-49"=>{"42"=>"lll", "47"=>"mnx"}}
doit(h, 15)
#=> {"0-14"=>{"11"=>"a", "12"=>"b"},
# "15-29"=>{"19"=>"c", "28"=>"xx", "29"=>"xyz"},
# "30-44"=>{"42"=>"lll"}, "45-59"=>{"47"=>"mnx"}}
doit(h, 20)
#=> {"0-19"=>{"11"=>"a", "12"=>"b", "19"=>"c"},
# "20-39"=>{"28"=>"xx", "29"=>"xyz"},
# "40-59"=>{"42"=>"lll", "47"=>"mnx"}}

参见 Enumerable#slice_whenHash#slice .

步骤如下。

group_size = 10
a = h.keys
#=> ["11", "12", "19", "28", "29", "42", "47", "74", "76"]
b = a.slice_when { |k1,k2| k2.to_i/group_size > k1.to_i/group_size }
#=> #<Enumerator: #<Enumerator::Generator:0x000056fa312199b8>:each>

我们可以看到将由该枚举器生成并通过将其转换为数组传递给 block 的元素。

b.to_a
#=> [["11", "12", "19"], ["28", "29"], ["42", "47"]]

最后,

b.each_with_object({}) do |key_group,g|
start_range = group_size * (key_group.first.to_i/group_size)
g["%d-%d" % [start_range, start_range+group_size-1]] =
h.slice(*key_group)
end
#=> {"10-19"=>{"11"=>"a", "12"=>"b", "19"=>"c"},
# "20-29"=>{"28"=>"xx", "29"=>"xyz"},
# "40-49"=>{"42"=>"lll", "47"=>"mnx"}}

注意:

  e = b.each_with_object({})
#=> #<Enumerator: #<Enumerator:
# #<Enumerator::Generator:0x0000560a0fc12658>:each>:
# each_with_object({})>
e.to_a
#=> [[["11", "12", "19"], {}], [["28", "29"], {}], [["42", "47"], {}]]

最后一步开始于枚举器e 生成一个值并将其传递给 block ,之后使用array decomposition 为 block 变量赋值。 .

key_group,g = e.next
#=> [["11", "12", "19"], {}]
key_group
#=> ["11", "12", "19"]
g #=> {}

然后执行 block 计算。

start_range = group_size * (key_group.first.to_i/group_size)
#=> 10 * (11/10) => 10
g["%d-%d" % [start_range, start_range+group_size-1]] =
h.slice(*key_group)
#=> g["%d-%d" % [10, 10+10-1]] = h.slice("11", "12", "19")
#=> g["10-19"] = {"11"=>"a", "12"=>"b", "19"=>"c"}
#=> {"11"=>"a", "12"=>"b", "19"=>"c"}

现在,

g #=> {"10-19"=>{"11"=>"a", "12"=>"b", "19"=>"c"}}  

枚举器 e 然后生成另一个元素,将其传递给 block 并分配 block 变量。

key_group,g = e.next
#=> [["28", "29"], {"10-19"=>{"11"=>"a", "12"=>"b", "19"=>"c"}}]
key_group
#=> ["28", "29"]
g #=> {"10-19"=>{"11"=>"a", "12"=>"b", "19"=>"c"}}

请注意,g 的值已更新。 block 计算现在像以前一样进行,之后:

g #=> {"10-19"=>{"11"=>"a", "12"=>"b", "19"=>"c"},
# "20-29"=>{"28"=>"xx", "29"=>"xyz"}}

然后

key_group,g = e.next
#=> [["42", "47"], {"10-19"=>{"11"=>"a", "12"=>"b", "19"=>"c"},
# "20-29"=>{"28"=>"xx", "29"=>"xyz"}}]
key_group
#=> ["42", "47"]
g #=> {"10-19"=>{"11"=>"a", "12"=>"b", "19"=>"c"},
# "20-29"=>{"28"=>"xx", "29"=>"xyz"}}

执行 block 计算后:

g #=> {"10-19"=>{"11"=>"a", "12"=>"b", "19"=>"c"},
# "20-29"=>{"28"=>"xx", "29"=>"xyz"},
# "40-49"=>{"42"=>"lll", "47"=>"mnx"}}

然后抛出一个异常:

key_group,g = e.next
#=> StopIteration (iteration reached an end)

使枚举器返回 g

关于ruby-on-rails - 从 ruby 中排列的哈希切片成 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63565896/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com