SEV*_*VEN 2 ruby ruby-on-rails ruby-hash
我试图为目录上的每种扩展类型创建一个具有一个键的哈希值。我想为每个键添加两个值:重复扩展名的次数以及具有该扩展名的所有文件的总大小。
\n与此类似的东西:
\n{".md" => {"ext_reps" => 6, "ext_size_sum" => 2350}, ".txt" => {"ext_reps" => 3, "ext_size_sum" => 1300}}
但我\xc2\xb4m坚持这一步:
\nhash = Hash.new{|hsh,key| hsh[key] = {}}\next_reps = 0\next_size_sum = 0\n\nDir.glob("/home/computer/Desktop/**/*.*").each do |file|\n hash[File.extname(file)].store "ext_reps", ext_reps\n hash[File.extname(file)].store "ext_size_sum", ext_size_sum \nend\n\np hash\nRun Code Online (Sandbox Code Playgroud)\n得到这个结果:
\n{".md" => {"ext_reps" => 0, "ext_size_sum" => 0}, ".txt" => {"ext_reps" => 0, "ext_size_sum" => 0}}
我找不到增加ext_reps和的方法ext_siz_sum
谢谢
\n假设绘制的文件扩展名和文件大小如下。
files = [{ ext: 'a', size: 10 },
{ ext: 'b', size: 20 },
{ ext: 'a', size: 30 },
{ ext: 'c', size: 40 },
{ ext: 'b', size: 50 },
{ ext: 'a', size: 60 }]
Run Code Online (Sandbox Code Playgroud)
您可以使用Hash#group_by和Hash#transform_values。
files.group_by { |h| h[:ext] }.
transform_values do |arr|
{ "ext_reps"=>arr.size, "ext_size_sum"=>arr.sum { |h| h[:size] } }
end
#=> {"a"=>{"ext_reps"=>3, "ext_size_sum"=>100},
# "b"=>{"ext_reps"=>2, "ext_size_sum"=>70},
# "c"=>{"ext_reps"=>1, "ext_size_sum"=>40}}
Run Code Online (Sandbox Code Playgroud)
请注意,第一个计算如下。
files.group_by { |h| h[:ext] }
#=> {"a"=>[{:ext=>"a", :size=>10}, {:ext=>"a", :size=>30},
# {:ext=>"a", :size=>60}],
# "b"=>[{:ext=>"b", :size=>20}, {:ext=>"b", :size=>50}],
# "c"=>[{:ext=>"c", :size=>40}]}
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用Hash#update(又名Hash#merge!)和Hash#merge的形式,它们使用块来计算正在合并的两个哈希中存在的键的值。(当带有 key 的键值对k被合并到正在构建的散列中时,Ruby 不会查阅该块(h当h没有 key时k)。)
有关返回正在合并的哈希的公共键值的块的三个参数的说明,请参阅文档。
files.each_with_object({}) do |g,h|
h.update(g[:ext]=>{"ext_reps"=>1, "ext_size_sum"=>g[:size]}) do |_k,o,n|
o.merge(n) { |_kk, oo, nn| oo + nn }
end
end
#=> {"a"=>{"ext_reps"=>3, "ext_size_sum"=>100},
# "b"=>{"ext_reps"=>2, "ext_size_sum"=>70},
# "c"=>{"ext_reps"=>1, "ext_size_sum"=>40}}
Run Code Online (Sandbox Code Playgroud)
_k我为“外部”和“内部”哈希(分别为和)的公共键选择了_kk以下划线开头的名称,以向读者表明它们未在块计算中使用。这是常见的做法。
请注意,此方法避免创建类似于创建的临时哈希group_by,因此往往比第一种方法使用更少的内存。
| 归档时间: |
|
| 查看次数: |
70 次 |
| 最近记录: |