Question

So array A is basically a relationship hash and I wanted to pull out all the matching nums or alphas to create a separate array which is B and C.

So once I have the B array, I can immediately know that alpha 'a' has num: 1 and 2 same thing with C, I can immediately know that num '1' has alpha a and b

 A = [{ alpha: 'a', num: '1'},
      { alpha: 'b', num: '1'},
      { alpha: 'a', num: '2'},
      { alpha: 'b', num: '2'}]

 B = [{alpha: 'a', num: [1, 2]},
      {alpha: 'b', num: [1, 2]}]

 C = [{num: '1', alpha: [a, b]},
      {num: '2', alpha: [a, b]}]

So far I have the following, but I think there must be a easier and more efficient way to do this.

B = []
C = []

A.each do |datum|
    if !B.any?{|value| value.alpha == datum.alpha}
      temp = {
          alpha: datum.alpha,
          num: (A.map {|value| (value.num == datum.num)? value.num : nil }).compact
      }

      B << temp
    end

    if !C.any?{|value| value.num == datum.num}
      temp = {
          num: datum.num,
          alpha: (A.map {|value| (value.alpha == datum.alpha)? value.alpha : nil }).compact
      }

      C << temp
    end
  end
Was it helpful?

Solution

Here is trick :

a = [
      { alpha: 'a', num: '1'},
      { alpha: 'b', num: '1'},
      { alpha: 'a', num: '2'},
      { alpha: 'b', num: '2'}
    ]

alpha_arry = a.group_by { |h| h[:alpha] }.map do |key,value| 
  {:alpha => key, :num => value.collect { |num_hash| num_hash[:num] }} 
end
alpha_arry
# => [{:alpha=>"a", :num=>["1", "2"]}, {:alpha=>"b", :num=>["1", "2"]}]
num_arry = a.group_by { |h| h[:num] }.map do |key,value| 
  {:num => key, :alpha => value.collect { |alpha_hash| alpha_hash[:alpha] }} 
end
num_arry
# => [{:num=>"1", :alpha=>["a", "b"]}, {:num=>"2", :alpha=>["a", "b"]}]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top