Вы правы, что хороший способ приблизиться к перемешиванию двумерного массива - это сгладить его и перемешать значения.Сложность в том, как вернуть перемешанные значения обратно в исходную структуру массива.
Превратив перемешанный массив в итератор iter
, мы можем вызвать iter.next()
, чтобы получить каждое значение и использовать вложенныеmap
s для доступа к исходным значениям и их замены:
var arr = [[1], [2, 3], [4, 5, 6]]
var iter = arr.joined().shuffled().makeIterator()
let arr2 = arr.map { $0.map { _ in iter.next()! } }
print(arr2)
[[4], [5, 1], [3, 6, 2]]
Превратите его в общую функцию: func shuffle2D<T>(_ arr: [[T]]) -> [[T]]
Мы можем превратить это в универсальную функцию, которая может перетасовать любой двумерный массив:
func shuffle2D<T>(_ arr: [[T]]) -> [[T]] {
var iter = arr.joined().shuffled().makeIterator()
return arr.map { $0.compactMap { _ in iter.next() }}
}
Примечание: Я изменил внутренний map
на compactMap
чтобы избежать распаковки силой iter.next()
.
Примеры:
print(shuffle2D([[1, 2, 3], [4, 5, 6]]))
[[2, 5, 6], [3, 1, 4]]
print(shuffle2D([["a", "b"], ["c", "d"], ["e", "f"]]))
[["e", "a"], ["b", "d"], ["f", "c"]]
let array = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
let shuffled = shuffle2D(array)
print(shuffled)
[[0, 1, 0, 1, 1, 0, 1, 1, 0, 0], [0, 1, 0, 0, 1, 1, 1, 2, 0, 1], [0, 1, 1, 1, 0, 1, 1, 1, 1, 1], [1, 0, 1, 0, 2, 1, 2, 1, 0, 1], [1, 0, 0, 0, 2, 1, 1, 0, 1, 1], [1, 1, 0, 0, 0, 0, 0, 1, 1, 1], [0, 0, 1, 1, 2, 0, 0, 1, 1, 0], [1, 0, 1, 1, 0, 0, 0, 1, 1, 0], [0, 0, 0, 1, 1, 0, 1, 1, 1, 0], [1, 1, 0, 0, 0, 0, 1, 0, 0, 0]]