2017-01-06 3 views
0

해시를 더 잘 이해하기 위해 노력하고 있으며 중복 된 항목이있는 문제를 발견했습니다. 항목을 계산하는 키를 추가하는 동안 이러한 항목의 해시를 반환해야합니다. 예를 들어 ...항목의 해시 (해시)가 주어지면 중복 항목을 통합하고 각 항목의 수를 제공하는 해시를 반환합니다.

나는 식료품 항목의 해시를 가지고 있으며 각 항목은 각 항목의 다양한 속성을 설명하는 다른 해시를 가리 킵니다.

groceries = [ 
    {"avocado" => {:price => 3.0, :on_sale => true}}, 
    {"tomato" => {:price => 1.0, :on_sale => false}}, 
    {"avocado" => {:price => 3.0, :on_sale => true}}, 
    {"kale" => {:price => 5.0, :on_sale => false}} 
] 

그리고 내 업데이트 식료품이 원하는 ...

groceries_updated = { 
    "avocado" => {:price => 3.0, :on_sale => true, :count => 2}, 
    "tomato" => {:price => 1.0, :on_sale => false, :count => 1}, 
    "kale" => {:price => 5.0, :on_sale => false, :count => 1} 
} 

나는 이런 식으로 뭔가를 할 수 있도록 먼저 원래 해시를 반복하여 나의 새로운 해시를 생성 한 내 초기 접근 방식. 그런 다음 원래 해시를 반복하고 새 해시 카운터를 늘립니다. 해시 반복에서이 작업을 수행 할 수 있는지 궁금합니다. 나는 또한 #each_with_object 메서드를 사용해 보았지만 매개 변수를 더 잘 이해해야합니다. #each_with_object를 사용하여 시도하면 : count 키가 추가되었지만 통합되지 않은 해시 배열이 생성됩니다.

def consolidate_cart(array) 
    array.each do |hash| 
    hash.each_with_object(Hash.new {|h,k| h[k] = {price: nil, clearance: nil, count: 0}}) do |(item, info), obj| 
     puts "#{item} -- #{info}" 
     puts "#{obj[item][:count] += 1}" 
     puts "#{obj}" 
    end 
    end 
end 
+0

이것은'inject'의 전형적인 경우입니다 – meagar

+4

위의 코드에서'avocado' 란 무엇입니까? 변수 또는 메소드 이름처럼 보입니다 (예 : Symbol 또는 String 키). 그렇다면 무엇이 반환됩니까? 해시는 각 키의 인스턴스를 하나만 가질 수 있으므로'{avocado : "foo", avocado : "bar"}'(': avocado'는 중복 된 Symbol 키입니다) {아보카도 : "바"}'. 명시된 문제를 해결하기 전에 데이터 구조를 재고해야합니다. –

+0

"나는'# each_with_object' 메소드를 사용해 보았습니다."이것은 거짓말입니다. 당신이 제공 한 입력으로는 아무 것도 시도 할 수 없습니다 : 유효한 루비 객체가 아닙니다. – mudasobwa

답변

0

다음과 같은 방법으로 통합 된 식료품을 구축 할 inject를 사용할 수 있습니다

groceries = [ 
    {"avocado" => {:price => 3.0, :on_sale => true}}, 
    {"tomato" => {:price => 1.0, :on_sale => false}}, 
    {"avocado" => {:price => 3.0, :on_sale => true}}, 
    {"kale" => {:price => 5.0, :on_sale => false}} 
] 

groceries_updated = groceries.inject({}) do |consolidated, grocery| 
    item = grocery.keys.first 
    consolidated[item] ||= grocery[item].merge(count: 0) 
    consolidated[item][:count] += 1 
    consolidated 
end 

inject (이 경우 {}에) 빌드 할 개체의 초기 상태를 취하고 블록 배열의 각 요소에 대해 호출됩니다. 블록의 목적은 개체를 수정/채우는 것입니다. inject을 사용하는 방법에 대한 설명은 here입니다.

귀하의 경우 블록은 해시에 새 항목을 추가하거나 이미 존재하는 경우 count을 증가시킵니다. 위의 코드는 해시에 새로운 항목을 추가하며, count이 0 인 경우에만 존재합니다 (즉, ||=). 그런 다음 count이 증가합니다. 주의 할

한 가지는 원래의 groceries 배열의 값이 다를 수 있습니다 것입니다 (예를 들어, 하나 개의 avocado 항목은 price 3.0의가있을 수 있습니다, 그리고 price 3.5의 또 다른). groceries_updated의 값은 원래 배열의 첫 번째 값을 포함합니다.