快速列出产品

Vin*_*van 2 list-comprehension swift

给定 Swift 中的两个列表:

let rows = ["a", "b", "c"]
let cols = ["1", "2", "3"]
Run Code Online (Sandbox Code Playgroud)

是否可以使用列表理解将它们组合起来以产生以下结果:

squares = ["a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3"]
Run Code Online (Sandbox Code Playgroud)

显然,它可以使用“for 循环”和类似的结构来完成,但我专门针对基于列表理解的解决方案。我知道 Swift 可以做一些列表理解(例如 let Evens = Array(filter(1..<10) { $0 % 2 == 0 }) ),但无法弄清楚它是否可以做类似于下面的事情哈斯克尔:

let squares = [ r ++ c | r <- rows, c <- cols]
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 5

一个可能的解决方案(现已更新为Swift 2):

let rows = ["a", "b", "c"]
let cols = ["1", "2", "3"]

let squares = rows.flatMap {
    row in
    cols.map {
        col in
        row + col
    }
}
print(squares)
// [a1, a2, a3, b1, b2, b3, c1, c2, c3]
Run Code Online (Sandbox Code Playgroud)

内部将数组map()映射cols到每个条目前面添加行号的数组。外部将数组flatMap()映射rows到数组的数组(每一行一个数组)并将结果展平。

更一般地说,可以将两个序列的“乘积”定义为具有所有组合的元组(对)数组:

func product<S : SequenceType, T : SequenceType>(lseq : S, _ rseq : T) -> [(S.Generator.Element, T.Generator.Element)] {
    return lseq.flatMap { left in
        rseq.map { right in
            (left, right)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将其用作

let squares = product(rows, cols).map(+)
Run Code Online (Sandbox Code Playgroud)