Skip to content

Commit bcb4dd1

Browse files
rjNemoclaude
andcommitted
docs: add documentation for new collection functions
Add comprehensive documentation for all new functions: - TakeWhile: take elements while predicate is true - DropWhile: drop elements while predicate is true - Scan: running accumulator (prefix scan) - First/FirstN: get first element(s) safely - Init: all but last element - Intersperse: insert separator between elements - Sliding: sliding window views - FoldRight: right-to-left fold/reduce - Tap: side effects without mutation - Transpose: flip matrix rows/columns - Unzip: split tuples into separate slices - ParallelReduce: parallel reduction (experimental) - Replicate: create n copies of a value Each doc includes: - Clear description - Code examples with output - Common use cases - Edge case handling 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 2651a33 commit bcb4dd1

File tree

15 files changed

+525
-0
lines changed

15 files changed

+525
-0
lines changed

.claude/settings.local.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(TestDropWhile\"\ngo test -bench=\"BenchmarkTakeWhile)",
5+
"Bash(gh pr create:*)",
6+
"Bash(TestTranspose)",
7+
"Bash(TestUnzip)",
8+
"Bash(TestParallelReduce)"
9+
],
10+
"deny": [],
11+
"ask": []
12+
}
13+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
title: "DropWhile"
3+
date: 2025-01-16T00:00:00-00:00
4+
---
5+
6+
`DropWhile` drops elements from the beginning of the slice while the predicate returns true. It returns the remaining elements starting from the first element where the predicate returns false.
7+
8+
```go
9+
package main
10+
11+
import (
12+
"fmt"
13+
u "github.com/rjNemo/underscore"
14+
)
15+
16+
func main() {
17+
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
18+
lessThan5 := func(n int) bool { return n < 5 }
19+
fmt.Println(u.DropWhile(nums, lessThan5)) // [5, 6, 7, 8, 9]
20+
21+
words := []string{"apple", "banana", "cherry", "date"}
22+
shortWords := func(s string) bool { return len(s) < 6 }
23+
fmt.Println(u.DropWhile(words, shortWords)) // ["banana", "cherry", "date"]
24+
}
25+
```

docs/content/collections/first.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
title: "First"
3+
date: 2025-01-16T00:00:00-00:00
4+
---
5+
6+
`First` returns the first element of the slice. Returns an error if the slice is empty.
7+
8+
```go
9+
package main
10+
11+
import (
12+
"fmt"
13+
u "github.com/rjNemo/underscore"
14+
)
15+
16+
func main() {
17+
nums := []int{1, 2, 3, 4, 5}
18+
first, err := u.First(nums)
19+
if err != nil {
20+
panic(err)
21+
}
22+
fmt.Println(first) // 1
23+
24+
// Handle empty slice
25+
empty := []int{}
26+
_, err = u.First(empty)
27+
if err != nil {
28+
fmt.Println("Error:", err) // Error: underscore: empty slice
29+
}
30+
}
31+
```

docs/content/collections/firstn.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
title: "FirstN"
3+
date: 2025-01-16T00:00:00-00:00
4+
---
5+
6+
`FirstN` returns the first n elements of the slice. If n is greater than the slice length, returns the entire slice. If n is less than or equal to 0, returns an empty slice.
7+
8+
```go
9+
package main
10+
11+
import (
12+
"fmt"
13+
u "github.com/rjNemo/underscore"
14+
)
15+
16+
func main() {
17+
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
18+
fmt.Println(u.FirstN(nums, 3)) // [1, 2, 3]
19+
fmt.Println(u.FirstN(nums, 0)) // []
20+
fmt.Println(u.FirstN(nums, 10)) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
21+
fmt.Println(u.FirstN(nums, -5)) // []
22+
}
23+
```
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
title: "FoldRight"
3+
date: 2025-01-16T00:00:00-00:00
4+
---
5+
6+
`FoldRight` is like Reduce but processes elements from right to left. Also known as foldr in Haskell. Important for non-associative operations where the order of evaluation matters.
7+
8+
```go
9+
package main
10+
11+
import (
12+
"fmt"
13+
u "github.com/rjNemo/underscore"
14+
)
15+
16+
func main() {
17+
// Subtraction is non-associative
18+
nums := []int{1, 2, 3}
19+
20+
// FoldRight: 1 - (2 - (3 - 0)) = 1 - (2 - 3) = 1 - (-1) = 2
21+
result := u.FoldRight(nums, 0, func(n, acc int) int { return n - acc })
22+
fmt.Println(result) // 2
23+
24+
// Compare with Reduce (left fold): (0 - 1) - 2 - 3 = -6
25+
leftResult := u.Reduce(nums, func(n, acc int) int { return acc - n }, 0)
26+
fmt.Println(leftResult) // -6
27+
28+
// Building a list in order
29+
buildList := u.FoldRight(nums, []int{}, func(n int, acc []int) []int {
30+
return append([]int{n}, acc...)
31+
})
32+
fmt.Println(buildList) // [1, 2, 3]
33+
34+
// String concatenation
35+
words := []string{"a", "b", "c"}
36+
concat := u.FoldRight(words, "", func(s, acc string) string { return s + acc })
37+
fmt.Println(concat) // "abc"
38+
}
39+
```

docs/content/collections/init.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
title: "Init"
3+
date: 2025-01-16T00:00:00-00:00
4+
---
5+
6+
`Init` returns all elements except the last one, and the last element separately. Returns an empty slice and zero value if the input slice is empty. Useful for destructuring lists from the right.
7+
8+
```go
9+
package main
10+
11+
import (
12+
"fmt"
13+
u "github.com/rjNemo/underscore"
14+
)
15+
16+
func main() {
17+
nums := []int{1, 2, 3, 4, 5}
18+
init, last := u.Init(nums)
19+
fmt.Println(init) // [1, 2, 3, 4]
20+
fmt.Println(last) // 5
21+
22+
// Single element
23+
single, val := u.Init([]int{42})
24+
fmt.Println(single) // []
25+
fmt.Println(val) // 42
26+
27+
// Empty slice
28+
empty, zero := u.Init([]int{})
29+
fmt.Println(empty) // []
30+
fmt.Println(zero) // 0
31+
}
32+
```
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
title: "Intersperse"
3+
date: 2025-01-16T00:00:00-00:00
4+
---
5+
6+
`Intersperse` inserts a separator between each element of the slice. Returns an empty slice if the input is empty. Returns the original element if the input has only one element.
7+
8+
```go
9+
package main
10+
11+
import (
12+
"fmt"
13+
u "github.com/rjNemo/underscore"
14+
)
15+
16+
func main() {
17+
nums := []int{1, 2, 3, 4, 5}
18+
fmt.Println(u.Intersperse(nums, 0)) // [1, 0, 2, 0, 3, 0, 4, 0, 5]
19+
20+
// Useful for formatting
21+
words := []string{"apple", "banana", "cherry"}
22+
fmt.Println(u.Intersperse(words, ",")) // ["apple", ",", "banana", ",", "cherry"]
23+
24+
// Single element - no separator added
25+
single := []int{42}
26+
fmt.Println(u.Intersperse(single, 0)) // [42]
27+
}
28+
```
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
title: "ParallelReduce"
3+
date: 2025-01-16T00:00:00-00:00
4+
---
5+
6+
`ParallelReduce` applies a reduction function in parallel using a worker pool. The operation must be associative and commutative for correct results. If workers <= 0, defaults to GOMAXPROCS. On error, the first error is returned and processing is canceled.
7+
8+
**Note:** This is an experimental function. Order of operations is not guaranteed, so use only with associative and commutative operations (like addition, multiplication, min, max).
9+
10+
```go
11+
package main
12+
13+
import (
14+
"context"
15+
"fmt"
16+
"time"
17+
u "github.com/rjNemo/underscore"
18+
)
19+
20+
func main() {
21+
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
22+
ctx := context.Background()
23+
24+
// Parallel sum (safe - addition is associative and commutative)
25+
result, err := u.ParallelReduce(ctx, nums, 4, func(ctx context.Context, n int, acc int) (int, error) {
26+
// Simulate expensive computation
27+
time.Sleep(10 * time.Millisecond)
28+
return n + acc, nil
29+
}, 0)
30+
31+
if err != nil {
32+
panic(err)
33+
}
34+
fmt.Println(result) // Result will vary due to parallel execution
35+
36+
// With context cancellation
37+
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
38+
defer cancel()
39+
40+
_, err = u.ParallelReduce(ctx, nums, 4, func(ctx context.Context, n int, acc int) (int, error) {
41+
time.Sleep(100 * time.Millisecond)
42+
return n + acc, nil
43+
}, 0)
44+
45+
if err != nil {
46+
fmt.Println("Operation was cancelled:", err)
47+
}
48+
}
49+
```
50+
51+
**Warning:** Do not use ParallelReduce for non-associative operations like subtraction or division, as the results will be unpredictable due to parallel execution order.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
title: "Replicate"
3+
date: 2025-01-16T00:00:00-00:00
4+
---
5+
6+
`Replicate` creates a slice containing count copies of value. Returns an empty slice if count is less than or equal to 0. Useful for initialization and testing.
7+
8+
```go
9+
package main
10+
11+
import (
12+
"fmt"
13+
u "github.com/rjNemo/underscore"
14+
)
15+
16+
func main() {
17+
// Basic usage
18+
fmt.Println(u.Replicate(3, "hello"))
19+
// ["hello", "hello", "hello"]
20+
21+
// Numbers
22+
fmt.Println(u.Replicate(5, 0))
23+
// [0, 0, 0, 0, 0]
24+
25+
// Zero count
26+
fmt.Println(u.Replicate(0, 42))
27+
// []
28+
29+
// Negative count
30+
fmt.Println(u.Replicate(-5, "x"))
31+
// []
32+
33+
// Use case: initialize with default values
34+
defaultScores := u.Replicate(10, 100)
35+
fmt.Println(defaultScores)
36+
// [100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
37+
38+
// Use case: creating separators
39+
separator := u.Replicate(40, "-")
40+
fmt.Println(u.Reduce(separator, func(s, acc string) string { return acc + s }, ""))
41+
// ----------------------------------------
42+
}
43+
```

docs/content/collections/scan.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
title: "Scan"
3+
date: 2025-01-16T00:00:00-00:00
4+
---
5+
6+
`Scan` is like Reduce but returns all intermediate accumulator values. Also known as prefix scan or cumulative fold. Useful for tracking running totals, running maximums, or other cumulative operations.
7+
8+
```go
9+
package main
10+
11+
import (
12+
"fmt"
13+
u "github.com/rjNemo/underscore"
14+
)
15+
16+
func main() {
17+
// Running sum
18+
nums := []int{1, 2, 3, 4}
19+
add := func(acc, n int) int { return acc + n }
20+
fmt.Println(u.Scan(nums, 0, add)) // [1, 3, 6, 10]
21+
22+
// Running maximum
23+
values := []int{3, 1, 4, 1, 5, 9, 2}
24+
max := func(acc, n int) int {
25+
if n > acc {
26+
return n
27+
}
28+
return acc
29+
}
30+
fmt.Println(u.Scan(values, 0, max)) // [3, 3, 4, 4, 5, 9, 9]
31+
32+
// String concatenation
33+
words := []string{"hello", "world", "!"}
34+
concat := func(acc, s string) string { return acc + s }
35+
fmt.Println(u.Scan(words, "", concat)) // ["hello", "helloworld", "helloworld!"]
36+
}
37+
```

0 commit comments

Comments
 (0)