我有薪金的對象,如數組:聚合上枚舉紅寶石
Person 1, Job 1, 400
Person 1, Job 1, 300
Person 1, Job 1, 300
Person 1, Job 2, 500
我想它們聚集和求和數,以便結果將是:
Person 1, Job 1, 1000
Person 1, Job 2, 500
我應該怎麼做?
我有薪金的對象,如數組:聚合上枚舉紅寶石
Person 1, Job 1, 400
Person 1, Job 1, 300
Person 1, Job 1, 300
Person 1, Job 2, 500
我想它們聚集和求和數,以便結果將是:
Person 1, Job 1, 1000
Person 1, Job 2, 500
我應該怎麼做?
class Salary
attr_reader :person, :job, :salary
def initialize(args={})
@person = args[:person]
@job = args[:job]
@salary = args[:salary]
end
def inspect
"<Person #{person}, Job #{job}, #{salary}>"
end
end
salaries = [
Salary.new({:person => 1, :job => 1, :salary => 400}),
Salary.new({:person => 1, :job => 1, :salary => 300}),
Salary.new({:person => 1, :job => 1, :salary => 300}),
Salary.new({:person => 1, :job => 2, :salary => 500})]
# => [<Person 1, Job 1, 400>, <Person 1, Job 1, 300>,
# <Person 1, Job 1, 300>, <Person 1, Job 2, 500>]
grouped_salaries = salaries.group_by do |salary|
[salary.person, salary.job]
end.map do |key, value|
Salary.new(person: key[0],
job: key[1],
salary: value.reduce(0) { |acc, s| acc + s.salary })
end
# => [<Person 1, Job 1, 1000>, <Person 1, Job 2, 500>]
你的數組包含一個類的實例。鑑於這個類,@Rafa已經回答了你的問題。你可能對班上有控制權,但是假設你沒有?假設你傳遞了該數組而其他人維護了這個類。我不確定這是否是好的做法,但這是我想要解決的情況。
此外,假設您只是想確定每個:person/:job pair
的總工資(而不是創建具有期望值的實例變量的類的實例)。您的陣列可能如下所示:
p salaries
#=> #<Salary:0x000001010cb230 @person=1, @job=1, @salary=400>,
#=> #<Salary:0x000001010cb1e0 @person=1, @job=1, @salary=300>,
#=> #<Salary:0x000001010cb190 @person=1, @job=1, @salary=300>,
#=> #<Salary:0x000001010cb140 @person=1, @job=2, @salary=500>]
很明顯,Salary類具有所需的三個實例變量。 (我生成此使用@拉法的類定義,但沒有attr_reader
和inspect
。)
Salaries.instance_methods(false) #=> []
告訴我們,對這些實例變量沒有干將。但是,我們可以使用Object#instance_variable_get來檢索它們的值。這是一個簡單的問題,按人員/工作對彙總工資:
def aggregate_salaries(salaries)
salaries
.group_by { |e| [e.instance_variable_get(:@person),
e.instance_variable_get(:@job)] }
.map do |(person,job),ae|
tot_sal = ae.reduce(0) { |t,e| t + e.instance_variable_get(:@salary) }
{person: person, job: job, salary: tot_sal}
end
end
aggregate_salaries(salaries)
#=> [{:person=>1, :job=>1, :salary=>1000},
# {:person=>1, :job=>2, :salary=>500}]
謝謝!爲了方便添加新的屬性,我修改了'map'塊: 'end.values.map do | group |' 'person = group [0]' 'person.salary =(group.map&薪水).reduce:+' 'person' 'end' –