Vince O'Sullivan - 1 year ago 87

Swift Question

Given two lists in Swift:

`let rows = ["a", "b", "c"]`

let cols = ["1", "2", "3"]

Is it possible to combine them using list comprehension to produce the following:

`squares = ["a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3"]`

Obviously, it can be done using a "for loop" and similar constructs, but I'm specifically for a list comprehension based solution. I know Swift can do some list comprehension (e.g. let evens = Array(filter(1..<10) { $0 % 2 == 0 }) ) but can't figure out if it can do something similar to the following piece of Haskell:

`let squares = [ r ++ c | r <- rows, c <- cols]`

Answer Source

A possible solution (now updated for **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]
```

The inner `map()`

maps the `cols`

array to an array with the
row number prepended to each entry. The outer `flatMap()`

maps
the `rows`

array to an array of arrays (one for each row) *and flattens* the result.

Slightly more general, one could define the "product" of two sequences as an array of tuples (pairs) with all combinations:

```
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)
}
}
}
```

and then use it as

```
let squares = product(rows, cols).map(+)
```