-
Notifications
You must be signed in to change notification settings - Fork 2
/
unique.go
40 lines (36 loc) · 1.23 KB
/
unique.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package fungi
// Unique returns a stream of unique items. The incoming stream must be a stream
// of comparable items.
func Unique[T comparable](items Stream[T]) Stream[T] {
return UniqueBy(Identity[T])(items)
}
// UniqueBy accepts a stream of any items and returns a stream of unique items.
// To be able to do that efficiently, it requires a function that can convert
// a stream item into something comparable. It's like a hashing function, but it
// doesn't have to be.
//
// For example, let's say there's a struct called User:
//
// type User struct {
// ID int // unique database identifier
// Name string
// }
//
// You can create a stream of unique users like so:
//
// var usersStream fungi.Stream[*User] = service.GetUsers()
// // usersStream might contain duplicates
// uniqueUsers := fungi.UniqueBy(func(u *User) int { return u.ID })
// uniqueUsersStream := uniqueUsers(usersStream)
func UniqueBy[T any, K comparable](id func(T) K) StreamIdentity[T] {
memory := make(map[K]struct{})
unique := FilterMap(func(item T) (T, bool) {
key := id(item)
_, seen := memory[key]
memory[key] = struct{}{}
return item, !seen
})
return StreamIdentity[T](unique)
}
func Identity[T any](item T) T { return item }
func Nop[T any](_ T) {}