Arrays Ruby:多维数组到一维行
在Ruby中,我该如何着手:Arrays Ruby:多维数组到一维行,arrays,ruby,multidimensional-array,Arrays,Ruby,Multidimensional Array,在Ruby中,我该如何着手: [ 1, ["green", "blue", "black"], [ ["1", "2"], ["3"], ["4", "5"] ] ] 这个 [ [1, "green", "1"], [1, "green", "2"], [1, "blue", "3"], [1, "black", "4"], [1, "black", "5"], ] 我试过了,但是运气不好。非常感谢您提供的任何帮助,当然我正在寻找性能解决方案。我并不完全清
[
1,
["green", "blue", "black"],
[ ["1", "2"], ["3"], ["4", "5"] ]
]
这个
[
[1, "green", "1"],
[1, "green", "2"],
[1, "blue", "3"],
[1, "black", "4"],
[1, "black", "5"],
]
我试过了,但是运气不好。非常感谢您提供的任何帮助,当然我正在寻找性能解决方案。我并不完全清楚模式,但这得到了您提供的示例的预期输出:
data[1].
zip(data[2]).
flat_map { |x, ys| [x].product(ys) }.
map { |zs| [data[0], *zs] }
#=> [[1, "green", "1"], [1, "green", "2"], [1, "blue", "3"],
# [1, "black", "4"], [1, "black", "5"]]
我们被给予
arr = [1, ["green", "blue", "black"], [ ["1", "2"], ["3"], ["4", "5"] ]]
以下是获得所需结果的几种方法
#1
arr[1].flat_map.with_index { |color,i| [arr[0]].product([color], arr[2][i]) }
#=> [[1, "green", "1"], [1, "green", "2"], [1, "blue", "3"],
# [1, "black", "4"], [1, "black", "5"]]
步骤如下
enum0 = arr[1].flat_map
#=> #<Enumerator: ["green", "blue", "black"]:flat_map>
enum1 = enum0.with_index
#=> #<Enumerator: #<Enumerator: ["green", "blue", "black"]:flat_map>:with_index>
b = arr[1].zip(arr[2])
#=> [["green", ["1", "2"]], ["blue", ["3"]], ["black", ["4", "5"]]]
生成第一个值并传递给块,分配块变量并执行块计算
color, i = enum1.next
#=> ["green", 0]
color
#=> "green"
i #=> 0
[arr[0]].product([color], arr[2][i])
#=> [1].product(["green"], )
#=> [[1, "green", "1"], [1, "green", "2"]]
color, a = b[0]
#=> ["green", ["1", "2"]]
color
#=> "green"
a #=> ["1", "2"]
[arr[0]].product([color], a)
#=> [["1"]].product(["green"], ["1", "2"])
#=> [[1, "green", "1"], [1, "green", "2"]]
由enum1
生成的其余两个元素的计算结果类似
另一种方法是duparr[2]
并移动dup的元素:
a2 = arr[2].dup
arr[1].flat_map { |color,i| [arr[0]].product([color], a2.shift) }
#2
arr[1].zip(arr[2]).flat_map { |color, a| [arr[0]].product([color], a) }
#=> [[1, "green", "1"], [1, "green", "2"], [1, "blue", "3"],
# [1, "black", "4"], [1, "black", "5"]]
步骤如下
enum0 = arr[1].flat_map
#=> #<Enumerator: ["green", "blue", "black"]:flat_map>
enum1 = enum0.with_index
#=> #<Enumerator: #<Enumerator: ["green", "blue", "black"]:flat_map>:with_index>
b = arr[1].zip(arr[2])
#=> [["green", ["1", "2"]], ["blue", ["3"]], ["black", ["4", "5"]]]
b[0]
被传递到flat\u map
,分配块变量并执行块计算
color, i = enum1.next
#=> ["green", 0]
color
#=> "green"
i #=> 0
[arr[0]].product([color], arr[2][i])
#=> [1].product(["green"], )
#=> [[1, "green", "1"], [1, "green", "2"]]
color, a = b[0]
#=> ["green", ["1", "2"]]
color
#=> "green"
a #=> ["1", "2"]
[arr[0]].product([color], a)
#=> [["1"]].product(["green"], ["1", "2"])
#=> [[1, "green", "1"], [1, "green", "2"]]
将
b
的其余元素传递到map
后,返回所需的数组。与建议的解决方案相比,我需要一个更通用、更灵活的解决方案(我的缺点是,我应该更清楚要求),因此我提出了以下建议:
class Array
def transpose_rows
arys = self.select{|el| el.is_a?(Array)}
if arys.size == 0
[self]
else
result = []
(arys.map(&:size).max || 1).times.map{ |i|
self.map { |r|
r.is_a?(Array) ? r[i] : r
}.transpose_rows.map{|r| result << r}
}
result
end
end
end
[
2,
[3,4,5],
6,
[7,8,9],
[ [11,22], [33], [44,55] ],
[0, 1, 2],
[ [66], [77], [nil,99] ],
4
].transpose_rows
# => [
# [2, 3, 6, 7, 11, 0, 66, 4],
# [2, 3, 6, 7, 22, 0, nil, 4],
# [2, 4, 6, 8, 33, 1, 77, 4],
# [2, 5, 6, 9, 44, 2, nil, 4],
# [2, 5, 6, 9, 55, 2, 99, 4]
# ]
谢谢,托克兰。作为一个平面地图的信徒,我应该看到这一点。我编辑过。当你给出一个例子时,给每个输入对象分配一个变量是很有帮助的(例如,
arr=[1、[“绿色”、“蓝色”、“黑色”]、[[“1”、“2”]、[“3”]、[“4”、“5”]]]
。这样,读者就可以在答案和注释中引用变量,而无需定义它们,所有读者都将使用相同的变量名。