376dc89f458bb3b9ac3fd4d559098645

This chunk of code takes an array of hashes and groups it by "callid". Does this by creating a temporary array of unique callid's and then feeding them into a new "grouped" array using the callid as an index. The result is an array of arrays of hashes as per the example after the grouping code. This works, but I have to think that there is a cleaner method of restructuring this data in this way.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# given this structure:
array_of_hashes = [
  {:callid => '1', :foo => '1', :created_at => '2007-09-21 11:45:15'}, 
  {:callid => '1', :foo => '2', :created_at => '2007-09-21 11:45:16'},
  {:callid => '2', :foo => '1', :created_at => '2007-09-21 11:45:19'}, 
  {:callid => '2', :foo => '2', :created_at => '2007-09-21 11:45:20'},
  {:callid => '3', :foo => '1', :created_at => '2007-09-21 11:45:21'}
]

# group using this:
array_of_arrays_of_hashes = returning([]) do |grouped_array|
  array_of_hashes.map {|x| x[:callid]}.uniq.each do |callid|
    grouped_array[callid.to_i] = array_of_hashes.select {|y| y[:callid] == callid}
  end
end.compact

# and this is the result:
array_of_arrays_of_hashes == [
  [{:callid=>"1", :foo=>"1", :created_at=>"2007-09-21 11:45:15"}, 
   {:callid=>"1", :foo=>"2", :created_at=>"2007-09-21 11:45:16"}], 

  [{:callid=>"2", :foo=>"1", :created_at=>"2007-09-21 11:45:19"}, 
   {:callid=>"2", :foo=>"2", :created_at=>"2007-09-21 11:45:20"}], 

  [{:callid=>"3", :foo=>"1", :created_at=>"2007-09-21 11:45:21"}]
]

Refactorings

No refactoring yet !

Avatar

dudemeister

October 1, 2007, October 01, 2007 15:30, permalink

No rating. Login to rate!

With group_by (found e.g. in rails), and methodphitamine:

1
2
3
4
# ...

# group using this:
array_of_arrays_of_hashes = array_of_hashes.group_by(&its[:callid]).values
Ada486a7a6724ac155c537674f6942ae

hungryblank

October 1, 2007, October 01, 2007 15:40, permalink

No rating. Login to rate!

I thought for you it was important array_of_arrays_of_hashes[idx] would return the array with the idx caller id.
But is not because after you apply the compact method and this breaks the relationship between array_of_arrays_of_hashes index and callid.
In this case the code below should be enough.

1
2
3
array_of_arrays_of_hashes = array_of_hashes.map { |e| e[:callid] }.uniq.inject([]) do |grouped_array, callid|
  grouped_array << array_of_hashes.select { |h| h[:callid] == callid }
end
376dc89f458bb3b9ac3fd4d559098645

Jarrod

October 3, 2007, October 03, 2007 10:16, permalink

No rating. Login to rate!

dudemeister... great solution, though it should be mentioned that the methodphitamine gem is required to use the &its style syntax (which is freaking awesome)

http://jicksta.com/articles/2007/08/04/the-methodphitamine

Your refactoring





Format Copy from initial code

or Cancel