开发者

One-liner Algorithm to Combine Arrays into Arrays of All Possible Value Combinations?

开发者 https://www.devze.com 2023-02-05 23:55 出处:网络
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:

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))
0

精彩评论

暂无评论...
验证码 换一张
取 消