Skip to content

Commit 5119c2d

Browse files
committed
set.intersection
1 parent 915f43c commit 5119c2d

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
`from_list`, `fold`, `run`, `to_list`, `take`, `drop`, `map`, `filter`,
77
`cycle`, and `range` functions.
88
- Created the `set` module with the `new`, `insert`, `delete`, `to_list`,
9-
`from_list`, `fold`, `take`, and `contains` functions.
9+
`from_list`, `fold`, `take`, `union`, `intersection`, and `contains`
10+
functions.
1011
- Created the `io` module with the `print`, `println`, and `debug` functions.
1112
- Created the `queue` module with the `new`, `from_list`, `to_list`,
1213
`is_empty`, `length`, `push_back`, `push_front`, `pop_back`, `pop_front`,

src/gleam/set.gleam

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,44 @@ pub fn take(
169169
) -> Set(member) {
170170
Set(map.take(from: set.map, keeping: desired))
171171
}
172+
173+
fn order(
174+
first: Set(member),
175+
second: Set(member),
176+
) -> tuple(Set(member), Set(member)) {
177+
case map.size(first.map) > map.size(second.map) {
178+
True -> tuple(first, second)
179+
False -> tuple(second, first)
180+
}
181+
}
182+
183+
/// Create a new set that contains all members of both given sets.
184+
///
185+
/// This function runs in loglinear time.
186+
///
187+
/// ## Examples
188+
///
189+
/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list
190+
/// [1, 2, 3]
191+
///
192+
pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) {
193+
let tuple(larger, smaller) = order(first, second)
194+
fold(over: smaller, from: larger, with: fn(m, a) { insert(a, m) })
195+
}
196+
197+
/// Create a new set that contains members that are present in both given sets.
198+
///
199+
/// This function runs in loglinear time.
200+
///
201+
/// ## Examples
202+
///
203+
/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list
204+
/// [2]
205+
///
206+
pub fn intersection(
207+
of first: Set(member),
208+
and second: Set(member),
209+
) -> Set(member) {
210+
let tuple(larger, smaller) = order(first, second)
211+
take(from: larger, keeping: to_list(smaller))
212+
}

test/gleam/set_test.gleam

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,15 @@ pub fn take_test() {
7979
|> set.take([1, 3, 5])
8080
|> should.equal(set.from_list([1, 3]))
8181
}
82+
83+
pub fn union_test() {
84+
set.union(set.from_list([1, 2]), set.from_list([2, 3]))
85+
|> set.to_list
86+
|> should.equal([1, 2, 3])
87+
}
88+
89+
pub fn intersection_test() {
90+
set.intersection(set.from_list([1, 2]), set.from_list([2, 3]))
91+
|> set.to_list
92+
|> should.equal([2])
93+
}

0 commit comments

Comments
 (0)