0

Suppose I have a hash

@attribute_type = {
  typeA: ['a', 'b', 'c'],
  typeB: ['1', '2', '3'],
  typeC: ['9', '8', '7']
}

I want to iterate over the values so I can create an array having all distinct possible combinations of the three arrays, for example:

['a', '1', '9'], ['a', '1', '8'], ['a', '1', '7'], ['a', '2', '9'], ...

Is this possible?

5
  • The answer you selected offers the possible combinations of type[:A] in combination with types B and C. However your question states "all possible combinations" in which case h.values.flatten.combination(3).to_a is potentially more correct depending on if you meant distinct values or permutations. Right now based on the chosen answer ["a","b","c"] is not considered a valid "combination" so "all" might be misleading Commented May 25, 2018 at 17:44
  • I meant all distinct possible combinations. I'll edit the question to reflect this. Thank you. Commented May 29, 2018 at 0:40
  • So would ["a", "b", 1] be considered valid? If so the selected answer does not cover this. Nor does your example to be honest Commented May 29, 2018 at 0:54
  • No I just want all distinct possible combinations from the three arrays. I don't know how to word it. Can you please help me with that? What I want is the combination of 1 value per set inside the array, so like {typeA * typeB * typeC}, but I want the values for each combination. Commented May 29, 2018 at 2:26
  • 1
    Your description seems sufficient based on the answer you selected I was just looking clarification to make sure. Commented May 29, 2018 at 12:56

2 Answers 2

11
h = { :typeA=>['a','b','c'], :typeB=>['1','2','3'], :typeC=>['9','8','7'] }

first, *rest = h.values
  #=> [["a", "b", "c"], ["1", "2", "3"], ["9", "8", "7"]]
first.product(*rest)
  #=> [["a", "1", "9"], ["a", "1", "8"], ["a", "1", "7"],
  #    ["a", "2", "9"], ["a", "2", "8"], ["a", "2", "7"],
  #    ["a", "3", "9"], ["a", "3", "8"], ["a", "3", "7"],
  #    ["b", "1", "9"], ["b", "1", "8"], ["b", "1", "7"],
  #    ["b", "2", "9"], ["b", "2", "8"], ["b", "2", "7"],
  #    ["b", "3", "9"], ["b", "3", "8"], ["b", "3", "7"],
  #    ["c", "1", "9"], ["c", "1", "8"], ["c", "1", "7"],
  #    ["c", "2", "9"], ["c", "2", "8"], ["c", "2", "7"],
  #    ["c", "3", "9"], ["c", "3", "8"], ["c", "3", "7"]]

See Array#product.

Sign up to request clarification or add additional context in comments.

4 Comments

If you don't mind me asking, what does first, *rest = h.values mean? I don't get the first part, and the comma as well.
Suppose arr = [[1,2,3], [4,5,6], [7,8,9]]. Let's try it: first, *rest = arr; first #=> [1,2,3]; rest #=> [[4,5,6], [7,8,9]]. The asterisk is called a splat. This article provides a good explanation, especially the section Array Destruction.
I think your autocorrect meant to let you say Destructuring in that comment.
@IBG you can also target the values explicitly, i.e. h[:typeA].product(h[:typeB], h[:typeC])
1

My 2 cents.

Pretty the same as Cary Swoveland, but just one line:

h.values.first.product(*h.values.drop(1))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.