Skip to content

Commit 931d454

Browse files
sportolpil
authored andcommitted
Add list.transpose and list.interleave
1 parent 8efb599 commit 931d454

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Unreleased
44

5-
- The `list` module gains the `flat_map` function.
5+
- The `list` module gains the `interleave`, `flat_map` and `transpose` functions.
66
- The `option` module gains the `all` and `values` functions.
77
- The `result` module gains the `values` function.
88
- All modules now use the new `#(a, b, ...)` tuple syntax.

src/gleam/list.gleam

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,3 +1522,48 @@ pub fn combination_pairs(items: List(a)) -> List(#(a, a)) {
15221522
do_combination_pairs(items)
15231523
|> flatten
15241524
}
1525+
1526+
/// Make a list alternating the elements from the given lists
1527+
///
1528+
/// ## Examples
1529+
///
1530+
/// ```
1531+
/// > list.interleave([[1, 2], [101, 102], [201, 202]])
1532+
/// [1, 101, 201, 2, 102, 202]
1533+
/// ```
1534+
///
1535+
pub fn interleave(list: List(List(a))) -> List(a) {
1536+
transpose(list)
1537+
|> flatten
1538+
}
1539+
1540+
/// Transpose rows and columns of the list of lists.
1541+
///
1542+
/// ## Examples
1543+
///
1544+
/// ```
1545+
/// > transpose([[1, 2, 3], [101, 102, 103]])
1546+
/// [[1, 101], [2, 102], [3, 103]]
1547+
/// ```
1548+
pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) {
1549+
let take_first = fn(list) {
1550+
case list {
1551+
[] -> []
1552+
[f] -> [f]
1553+
[f, .._rest] -> [f]
1554+
}
1555+
}
1556+
1557+
case list_of_list {
1558+
[] -> []
1559+
[[], ..xss] -> transpose(xss)
1560+
rows -> {
1561+
let firsts =
1562+
rows
1563+
|> map(take_first)
1564+
|> flatten
1565+
let rest = transpose(map(rows, drop(_, 1)))
1566+
[firsts, ..rest]
1567+
}
1568+
}
1569+
}

test/gleam/list_test.gleam

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,3 +692,33 @@ pub fn combination_pairs_test() {
692692
list.combination_pairs([1, 2, 3, 4])
693693
|> should.equal([#(1, 2), #(1, 3), #(1, 4), #(2, 3), #(2, 4), #(3, 4)])
694694
}
695+
696+
pub fn interleave_test() {
697+
list.interleave([[1, 2], [101, 102]])
698+
|> should.equal([1, 101, 2, 102])
699+
700+
list.interleave([[1, 2], [101, 102], [201, 202]])
701+
|> should.equal([1, 101, 201, 2, 102, 202])
702+
703+
// Left over elements are added at the end
704+
list.interleave([[1, 2, 3], [101, 102]])
705+
|> should.equal([1, 101, 2, 102, 3])
706+
707+
list.interleave([[1, 2], [101, 102, 103]])
708+
|> should.equal([1, 101, 2, 102, 103])
709+
}
710+
711+
pub fn transpose_test() {
712+
list.transpose([[1, 2, 3], [101, 102, 103]])
713+
|> should.equal([[1, 101], [2, 102], [3, 103]])
714+
715+
list.transpose([[1, 2, 3], [101, 102, 103], [201, 202, 203]])
716+
|> should.equal([[1, 101, 201], [2, 102, 202], [3, 103, 203]])
717+
718+
// Left over elements are still returned
719+
list.transpose([[1, 2], [101, 102, 103]])
720+
|> should.equal([[1, 101], [2, 102], [103]])
721+
722+
list.transpose([[1, 2, 3], [101, 102], [201, 202, 203]])
723+
|> should.equal([[1, 101, 201], [2, 102, 202], [3, 203]])
724+
}

0 commit comments

Comments
 (0)