2014-12-02 1 views
4

에 같은 경우 해시를 병합하는 방법 :지정된 키의 값이 같은 해시의 배열을 가지고 배열

[ {:foo=>2, :date=>Sat, 01 Sep 2014}, 
{:foo2=>2, :date=>Sat, 02 Sep 2014}, 
{:foo3=>3, :date=>Sat, 01 Sep 2014}, 
{:foo4=>4, :date=>Sat, 03 Sep 2014}, 
    {:foo5=>5, :date=>Sat, 02 Sep 2014}] 

을 그리고 나는 :date이 같은 경우 해시를 병합 할. 나는 위의 배열에서 무엇을 기대 은 다음과 같습니다

[ {:foo=>2, :foo3=>3, :date=>Sat, 01 Sep 2014}, 
{:foo2=>2, :foo5=>5 :date=>Sat, 02 Sep 2014}, 
{:foo4=>4, :date=>Sat, 03 Sep 2014}] 

내가 어떻게 할 수 있습니까?

아마도 데이터 구조 자체를 다시 생각해야합니까? 예를 들어 date 값을 해시 키로 사용해야합니까? 여기

+0

아니요, '날짜'클래스입니다. 왜? – ironsand

+0

해시 정의가 유효하지 않습니다. 우리가 당신을 도우려고 할 때 재사용이 중요하므로 루비가 그들을 받아 들일 수 있도록하십시오. –

답변

7

는 선 (demo)에서 할 수있는 방법은 다음과 같습니다

hashes.group_by{|h| h[:date] }.map{|_, hs| hs.reduce(:merge)} 

이 코드는 다음을 각 :date 그룹에 대한 자신의 :date 값을 기준으로

  • 그룹의 모든 해시
  • , 모든 해시를 가져 와서 하나의 해시로 병합합니다.

편집 : tokland와 Cary Swoveland가 제안한 수정 사항이 적용됩니다. 감사!

+0

nit-picking :'hashes.group_by {| h | h [: date]} .map {| k, hs | hs.reduce (: merge)}' – tokland

+0

좋은 해결책입니다. 독자가 블록에서 키를 사용하지 않는다고 말할 때'| _, hs | '라고 생각할 수도 있습니다. 그것은 꽤 작은 블록이므로 명백 할 수도 있지만 여전히 ... –

0

당신은 해시 모두 병합 될에 포함되어있는 키의 값을 해결하기 위해 블록을 사용하는 Hash#update (일명, merge!)의 형태로의 사용을 만들 수 있습니다.

arr = [ {:foo=>2, :date=>'Sat, 01 Sep 2014'}, 
     {:foo2=>2, :date=>'Sat, 02 Sep 2014'}, 
     {:foo3=>3, :date=>'Sat, 01 Sep 2014'}, 
     {:foo4=>4, :date=>'Sat, 03 Sep 2014'}, 
     {:foo5=>5, :date=>'Sat, 02 Sep 2014'}] 

arr.each_with_object({}) do |g,h| 
    h.update({ g[:date]=>g }) { |_,o,n| o.merge(n) } 
end.values 
    #=> [{:foo=>2, :date=>"Sat, 01 Sep 2014", :foo3=>3}, 
    # {:foo2=>2, :date=>"Sat, 02 Sep 2014", :foo5=>5}, 
    # {:foo4=>4, :date=>"Sat, 03 Sep 2014"}] 

I는 블록에서 사용되지 그 때문에 키 값을 포함하는 블록 변수에 대한 자리 _을 사용했다.

관련 문제