我是Ruby的新手。我需要根据长度生成对象的所有组合。
例如,array = [obj1, obj2, obj3]
,length = 2
,则组合为:
[
[obj1, obj1],
[obj1, obj2],
[obj1, obj3],
# ...
[obj3, obj3]
]
我知道我可以使用repeated_permutation
方法解决此问题,但我还需要能够过滤一些排列。例如,过滤掉两个相同对象是一个接一个的排列,即像[obj1, obj1]
一样。
答案 0 :(得分:3)
如果您只需删除任何相同obj的对,则可以使用permutation
方法。
arr = [1,2,3]
arr.permutation(2).to_a
#=> [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
答案 1 :(得分:2)
通过一个块来执行"过滤"。因此,要删除具有相同元素的内容,请使用:
a = [1,2,3]
a.repeated_permutation(2).reject { |permutation| permutation.uniq.one? }
#=> [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
答案 2 :(得分:2)
给定一个任意输入数组:
a = [1, 2, 3, 3, 4]
如果只希望生成唯一的排列,那么您只需执行以下操作:
a.uniq.permutation(2)
(如果您知道初始数组包含唯一元素,则不需要uniq
。)
但是,作为一种更通用的解决方案,您必须这样做:
a.repeated_permutation(2).reject { |permutation| ** FILTER RULE GOES HERE ** }
例如,如果您希望过滤所有没有连续两次重复值的结果,那么您可以这样做:
a.repeated_permutation(2).reject do |permutation|
permutation.each_cons(2).any? {|x, y| x == y}
end
将这一点发挥到极致,这是一个通用的方法:
def filtered_permutations(array, length)
array.repeated_permutation(length).reject{|permutation| yield(permutation)}
end
# Or, if you prefer:
def filtered_permutations(array, length, &block)
array.repeated_permutation(length).reject(&block)
end
# Usage:
a = [1, 2, 3, 3, 4]
filtered_permutations(a, 2) {|permutation| permutation.each_cons(2).any? {|x, y| x == y} }
# Or, if you prefer:
filtered_permutations(a, 2) {|permutation| permutation.each_cons(2).any? {|consecutive| consecutive.uniq.one?} }