我試圖為目錄上的每種型別的擴展創建一個帶有一個鍵的哈希。對于每個鍵,我想添加兩個值:重復該擴展名的次數和具有該擴展名的所有檔案的總大小。
與此類似的東西:
{".md" => {"ext_reps" => 6, "ext_size_sum" => 2350}, ".txt" => {"ext_reps" => 3, "ext_size_sum" => 1300}}
但我被困在這一步:
hash = Hash.new{|hsh,key| hsh[key] = {}}
ext_reps = 0
ext_size_sum = 0
Dir.glob("/home/computer/Desktop/**/*.*").each do |file|
hash[File.extname(file)].store "ext_reps", ext_reps
hash[File.extname(file)].store "ext_size_sum", ext_size_sum
end
p hash
有了這個結果:
{".md" => {"ext_reps" => 0, "ext_size_sum" => 0}, ".txt" => {"ext_reps" => 0, "ext_size_sum" => 0}}
而且我找不到增加ext_reps和增加的方法ext_siz_sum
謝謝
uj5u.com熱心網友回復:
假設繪制的檔案擴展名和檔案大小如下。
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 }]
您可以使用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}}
請注意,第一個計算如下。
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}]}
另一種方法是使用Hash#update (aka Hash#merge!) 和Hash#merge的形式,它們使用一個塊來計算在被合并的兩個哈希中都存在的鍵的值。k(當帶有 key 的鍵值對被合并到正在構建的散列中時(h),當h沒有 key時,Ruby 不會查詢該塊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}}
我為“外部”和“內部”哈希(分別為_k和_kk)的公共鍵選擇了以下劃線開頭的名稱,以向讀者表明它們未用于塊計算。這是常見的做法。
請注意,這種方法避免了類似于創建的臨時哈希的創建group_by,因此與第一種方法相比,它往往使用更少的記憶體。
uj5u.com熱心網友回復:
這是一個受Cary Swoveland和BenFenner給出的答案啟發的解決方案
hash = {}
Dir.glob("/home/computer/Desktop/**/*.*").each do |file|
(hash[File.extname(file)] ||= []) << file.size
end
hash.transform_values! { |sizes| { "ext_reps" => sizes.count, "ext_size_sum" => sizes.sum } }
uj5u.com熱心網友回復:
有each_with_object和嵌套Hash.new
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 }]
files.each_with_object(Hash.new(Hash.new(0))) do |el, hash|
h = hash[el[:ext]]
hash[el[:ext]] =
{ "ext_reps" => h["ext_reps"] 1, "ext_size_sum" => h["ext_size_sum"] el[: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}}
uj5u.com熱心網友回復:
這不是最“類似 Ruby”的解決方案,但與您提供的示例一起,這可能是您最終最終得到的解決方案。你的主要問題是你從來沒有增加ext_reps價值,也沒有積累ext_size_sum價值。
hash = {}
Dir.glob('/home/computer/Desktop/**/*.*').each do |file|
file_extension = File.extname(file)
if hash[file_extension].nil?
# This is the first time this file extension has been seen, so initialize things for it.
hash[file_extension] = {}
hash[file_extension]['ext_reps'] = 0
hash[file_extension]['ext_size_sum'] = 0
end
# Increment/accumulate values.
hash[file_extension]['ext_reps'] = 1
hash[file_extension]['ext_size_sum'] = file.size
end
uj5u.com熱心網友回復:
這幾乎是對 Cary 和其他人的答案的重申,沒有臨時變數。(這更像是 Ruby 恕我直言。)
Dir.glob("*.*")
.group_by { |f| File.extname(f) }
.transform_values do |i|
{
"count" => i.count,
"size" => i.sum { |f| File.size(f) }
}
end
=> {".app"=>{"count"=>1, "size"=>96},
".sh-builder"=>{"count"=>1, "size"=>192},
".sh-names"=>{"count"=>1, "size"=>288},
".json"=>{"count"=>2, "size"=>5362},
".rb"=>{"count"=>1, "size"=>132}}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/510036.html
標籤:轨道上的红宝石红宝石
