One-liner Algorithm to Combine Arrays into Arrays of All Possible Value Combinations?
Not quite sure I have the question fully formed, but what I'm trying to do is basically this:
# where the indices correspond to attributes fore example:
# [type, status]
x = %w(a b)
y = %w(c d)
combine(x, y) #=> [["a", "b"], ["a", "d"], ["c", "a"], ["c", "b"]]
The order of the array is always the same, so the reverse of each, such as [b, a]
, are not included in the result.
What is this called and what's an efficient way to implement this?
I see Array#permutation, but that's not quite it...
This would hopefully work for any number of arrays and values: combine(*arrays)
Thanks!
Update
Here's a better example of what I'm looking for:
This (x | y).combination(x.length).to_a
produces the following:
x = ["front_door", "open"]
y = ["back_door", "closed"]
(x | y).combination(x.length).to_a
=> [["front_door", "open"], ["front_door", "back_door"], ["front_door", "closed"], ["open", "back_door"], ["open", "closed"], ["back_door", "closed"]]
The actual result I'm looking for is this:
=> [["front_door", "open"], ["front_door", "closed"], ["back_door", "open"], ["back_door", "closed"]]
Or if it were a longer array:
x = ["house", "front_door", "open"]
y = ["building", "back_door", "closed"]
compute(x, y)
=> ["house", "front_door", "open"], ["house", "back_door", "open"], ["house", "front_door", "closed"], ["house", "back_door", "closed"], ["building", "front_door", "open"], ["building", "back_开发者_如何学Godoor", "open"], ["building", "front_door", "closed"], ["building", "back_door", "closed"]
Any ideas?
x.zip(y).reduce(:product).map(&:flatten)
And for several arrays:
x.zip(y,z,w).reduce(:product).map(&:flatten)
(x | y ).combination(x.length).to_a
def combine(*arrays)
head, *tail = arrays.transpose
head.product(*tail)
end
combine(x, y)
combine(x, y, z, ...)
Side note digression: this is one of the scenarios in which you get the point that functional languages make about functions being the important stuff. The fact that you have to call an object's method in OOP forces you -in this case- to contrivedly get their head/tail. When you have product
as a function, for example in Python, you don't have this kind of problems:
itertools.product(*zip(*arrays))
精彩评论