【问题标题】:Condensing multidimensional array of permutations into groups将排列的多维数组压缩成组
【发布时间】:2017-12-13 19:08:11
【问题描述】:

我在 Ruby 中有一个多维数组,如下所示:

[[1,12], [1,5], [1,6], [5,12], [6,12], [12,5], [12,6]]

我需要将它组合成一个新的多维数组,将值组合在一起,以形成 (n) 个位置的有效组合(n 是每个元素的大小原始数组):

[
  [[1,5,6], [12]], # [1,5,6].product([12]) #=> [[1, 12], [5, 12], [6, 12]]
  [[1,12], [5,6]]  # [1,12].product([5,6]) #=> [[1, 5], [1, 6], [12, 5], [12, 6]]
]

这样做的目的是获取一个由 n 位排列组成的数组,并生成尽可能小的多维数组,其中列出了每个位置的有效数字(但不包括不存在的组合)在原始数组中)。

如何将包含 n 位排列的多维数组简化为上述数组? Ruby 中内置的(和出色的)数组方法似乎没有为此提供函数,并且没有生成所有可能的组合,然后针对原始排列进行测试,我不确定如何正确处理。

【问题讨论】:

  • 问题是什么?你试过什么?
  • 我不明白预期输出背后的原因。您说要创建 2 个位置的组合,但输出的长度为 3,1,2,2
  • 结果数组中的每个项目都包含 2 个数组,每个位置一个,包含该位置的有效条目(第一个位置为 [1,5,6],第二个位置为 [12]在第一项的情况下,[1,12] 在第一个位置,[5,6] 在第二个位置的第二个位置)。如果您查看 1,5,6 和 12 的所有可能排列,则此模式明确排除 [5,6] 和 [6,5] 作为第 1 和第 2 的有效排列,这就是我想要做的- 以上述格式表达 n 个位置的有限排列列表。
  • @RichardWalker 根据您的解释,我添加了两个 inline-cmets(希望我做对了)。

标签: arrays ruby multidimensional-array


【解决方案1】:

我不太确定我是否正确理解了这个问题,但是鉴于这个数组:

a = [[1, 12], [1, 5], [1, 6], [5, 12], [6, 12], [12, 5], [12, 6]]

我认为您可以将左侧项目按右侧项目分组:

h1 = Hash.new { |h, k| h[k] = [] }
a.each { |k, v| h1[v] << k }
h1
#=> {12=>[1, 5, 6], 5=>[1, 12], 6=>[1, 12]}

并再次应用相同的转换:

h2 = Hash.new { |h, k| h[k] = [] }
h1.each { |k, v| h2[v] << k }
h2
#=> {[1, 5, 6]=>[12], [1, 12]=>[5, 6]}

这给出了:

h2.to_a
#=> [
#     [[1, 5, 6], [12]],
#     [[1, 12], [5, 6]]
#   ]

在最新版本的 Ruby 中,您可以这样写:

a.group_by(&:last).transform_values { |v| v.map(&:first) }
 .group_by(&:last).transform_values { |v| v.map(&:first) }
 .to_a
#=> [
#     [[1, 5, 6], [12]],
#     [[1, 12], [5, 6]]
#   ]

压缩数组可以通过以下方式展开:

[[[1, 5, 6], [12]], [[1, 12], [5, 6]]].flat_map { |a, b| a.product(b) }
#=> [[1, 12], [5, 12], [6, 12], [1, 5], [1, 6], [12, 5], [12, 6]]

请注意,此尝试仅适用于具有两个元素的子数组,但它应该可以帮助您入门。

【讨论】:

  • 谢谢——这正是我想要达到的目标!我正在寻找对具有 3 个元素的子数组执行相同操作的方法,这将是一个很好的开始(我可能必须通过递归获得创意)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-25
  • 2015-12-31
  • 2020-12-11
  • 2011-05-20
  • 2017-10-16
  • 2020-06-24
  • 1970-01-01
相关资源
最近更新 更多