@@ -43,17 +43,17 @@ const safe = lo.unwrapOr(i32, null, 42); // 42
4343
4444## Function Index
4545
46- - [ Slice Helpers] ( #slice-helpers ) - first, last, nth, firstOr, lastOr, nthOr, initial, tail, drop, dropRight, dropWhile, dropRightWhile, take, takeRight, takeWhile, takeRightWhile, sample, samples
47- - [ Transform] ( #transform ) - map, mapAlloc, mapIndex, filter, filterAlloc, reject, rejectAlloc, compact, compactAlloc, flatten, flattenAlloc, flatMap, flatMapAlloc, without, forEach, forEachIndex
48- - [ Aggregate] ( #aggregate ) - reduce, reduceRight, sum, sumBy, product, productBy, mean, meanBy, min, max, minBy, maxBy, minMax, count, countBy, countValues, mode, median, variance, stddev, percentile
46+ - [ Slice Helpers] ( #slice-helpers ) - first, last, nth, firstOr, lastOr, nthOr, initial, tail, drop, dropRight, dropWhile, dropWhileAlloc, dropRightWhile, take, takeRight, takeWhile, takeWhileAlloc , takeRightWhile, sample, samples
47+ - [ Transform] ( #transform ) - map, mapAlloc, mapIndex, filter, filterAlloc, reject, rejectAlloc, compact, compactAlloc, flatten, flattenAlloc, flattenDeep, flatMap, flatMapAlloc, without, forEach, forEachIndex, compactMap, filterMapIter
48+ - [ Aggregate] ( #aggregate ) - reduce, reduceRight, sum, sumBy, product, productBy, mean, meanBy, min, max, minBy, maxBy, minMax, minMaxBy, count, countBy, countValues, mode, median, variance, stddev, sampleVariance, sampleStddev , percentile
4949- [ Sort & Order] ( #sort--order ) - sortBy, sortByAlloc, sortByField, sortByFieldAlloc, toSortedAlloc, isSorted, equal, reverse, shuffle
50- - [ Set Operations] ( #set-operations ) - uniq, uniqBy, intersect, union\_ , difference, symmetricDifference, findDuplicates, findUniques, elementsMatch
50+ - [ Set Operations] ( #set-operations ) - uniq, uniqBy, intersect, union\_ , difference, symmetricDifference, findDuplicates, findUniques, elementsMatch, differenceWith, intersectWith, unionWith
5151- [ Partition & Group] ( #partition--group ) - partition, groupBy, chunk, window, scan, scanAlloc
5252- [ Combine] ( #combine ) - concat, splice, interleave, fill, fillRange, repeat, repeatBy, times, timesAlloc
53- - [ Search] ( #search ) - find, findIndex, findLast, findLastIndex, indexOf, lastIndexOf, contains, containsBy, every, some, none, minIndex, maxIndex
53+ - [ Search] ( #search ) - find, findIndex, findLast, findLastIndex, indexOf, lastIndexOf, contains, containsBy, every, some, none, minIndex, maxIndex, binarySearch, lowerBound, upperBound, sortedIndex, sortedLastIndex
5454- [ Map Helpers] ( #map-helpers ) - keys, keysAlloc, values, valuesAlloc, entries, entriesAlloc, fromEntries, mapKeys, mapValues, filterMap, filterKeys, filterValues, pickKeys, omitKeys, invert, merge, assign, mapEntries, mapToSlice, valueOr, hasKey, mapCount, keyBy, associate
5555- [ String Helpers] ( #string-helpers ) - words, wordsAlloc, camelCase, pascalCase, snakeCase, kebabCase, capitalize, lowerFirst, toLower, toUpper, trim, trimStart, trimEnd, startsWith, endsWith, includes, substr, ellipsis, strRepeat, padLeft, padRight, runeLength, randomString, split, splitAlloc, join, replace, replaceAll, chunkString
56- - [ Math] ( #math ) - sum, mean, median, variance, stddev, percentile, lerp, remap, clamp, inRange, cumSum, cumProd, rangeAlloc, rangeWithStepAlloc
56+ - [ Math] ( #math ) - sum, mean, median, variance, stddev, sampleVariance, sampleStddev, percentile, lerp, remap, clamp, inRange, cumSum, cumProd, rangeAlloc, rangeWithStepAlloc
5757- [ Tuple Helpers] ( #tuple-helpers ) - zip, zipAlloc, zipWith, unzip, enumerate
5858- [ Type Helpers] ( #type-helpers ) - isNull, isNotNull, unwrapOr, coalesce, empty, isEmpty, isNotEmpty, ternary, toConst
5959- [ Types] ( #types ) - Entry, Pair, MinMax, RangeError, PartitionResult, UnzipResult, AssocEntry, and iterator types
@@ -154,6 +154,16 @@ Drop leading elements while the predicate returns true.
154154lo.dropWhile(i32, &.{ 1, 2, 3, 4 }, isLessThan3); // &.{ 3, 4 }
155155```
156156
157+ ### dropWhileAlloc
158+
159+ Drop leading elements while the predicate returns true. Allocates a copy. Caller owns the returned slice.
160+
161+ ``` zig
162+ const result = try lo.dropWhileAlloc(i32, allocator, &.{ 1, 2, 3, 4 }, isLessThan3);
163+ defer allocator.free(result);
164+ // result == &.{ 3, 4 }
165+ ```
166+
157167### dropRightWhile
158168
159169Drop trailing elements while the predicate returns true.
@@ -186,6 +196,16 @@ Take leading elements while the predicate returns true.
186196lo.takeWhile(i32, &.{ 1, 2, 3, 4 }, isLessThan3); // &.{ 1, 2 }
187197```
188198
199+ ### takeWhileAlloc
200+
201+ Take leading elements while the predicate returns true. Allocates a copy. Caller owns the returned slice.
202+
203+ ``` zig
204+ const result = try lo.takeWhileAlloc(i32, allocator, &.{ 1, 2, 3, 4 }, isLessThan3);
205+ defer allocator.free(result);
206+ // result == &.{ 1, 2 }
207+ ```
208+
189209### takeRightWhile
190210
191211Take trailing elements while the predicate returns true.
@@ -312,12 +332,25 @@ var it = lo.flatten(i32, &data);
312332
313333### flattenAlloc
314334
315- Flatten a slice of slices into an allocated slice. Caller owns the returned slice.
335+ Flatten a slice of slices into an allocated slice. Counts total elements first, then allocates once. Caller owns the returned slice.
316336
317337``` zig
318- const data = [_][]const i32{ &.{ 1, 2 }, &.{ 3, 4 } };
338+ const data = [_][]const i32{ &.{ 1, 2 }, &.{ 3, 4, 5 } };
319339const result = try lo.flattenAlloc(i32, allocator, &data);
320340defer allocator.free(result);
341+ // result == &.{ 1, 2, 3, 4, 5 }
342+ ```
343+
344+ ### flattenDeep
345+
346+ Flatten two levels of nesting (` [][][]T ` to ` []T ` ). Caller owns the returned slice.
347+
348+ ``` zig
349+ const inner = [_][]const i32{ &.{ 1, 2 }, &.{ 3 } };
350+ const outer = [_][]const []const i32{ &inner };
351+ const result = try lo.flattenDeep(i32, allocator, &outer);
352+ defer allocator.free(result);
353+ // result == &.{ 1, 2, 3 }
321354```
322355
323356### flatMap
@@ -362,6 +395,33 @@ Invoke a function on each element with its index.
362395lo.forEachIndex(i32, &.{ 10, 20 }, printWithIndex);
363396```
364397
398+ ### compactMap
399+
400+ Filter and map in a single pass. The transform returns ` ?R ` ; non-null values are collected into an allocated slice. Caller owns the returned slice.
401+
402+ ``` zig
403+ const toEvenDoubled = struct {
404+ fn f(x: i32) ?i32 {
405+ if (@mod(x, 2) == 0) return x * 2;
406+ return null;
407+ }
408+ }.f;
409+ const result = try lo.compactMap(i32, i32, allocator, &.{ 1, 2, 3, 4 }, toEvenDoubled);
410+ defer allocator.free(result);
411+ // result == &.{ 4, 8 }
412+ ```
413+
414+ ### filterMapIter
415+
416+ Filter and map in a single step. Returns a lazy iterator.
417+
418+ ``` zig
419+ var it = lo.filterMapIter(i32, i32, &.{ 1, 2, 3, 4 }, toEvenDoubled);
420+ it.next(); // 4
421+ it.next(); // 8
422+ it.next(); // null
423+ ```
424+
365425---
366426
367427## Aggregate
@@ -416,10 +476,10 @@ lo.productBy(i32, i64, &.{ 2, 3, 4 }, double); // 192
416476
417477### mean
418478
419- Arithmetic mean of a slice. Returns 0.0 for empty slices.
479+ Arithmetic mean of a slice. Returns null for empty slices.
420480
421481``` zig
422- lo.mean(i32, &.{ 2, 4, 6 }); // 4.0
482+ lo.mean(i32, &.{ 2, 4, 6 }).? ; // 4.0
423483```
424484
425485### meanBy
@@ -428,7 +488,7 @@ Arithmetic mean after applying a transform function.
428488
429489``` zig
430490const asF64 = struct { fn f(x: i32) f64 { return @floatFromInt(x); } }.f;
431- lo.meanBy(i32, &vals, asF64); // 20.0
491+ lo.meanBy(i32, &vals, asF64).? ; // 20.0
432492```
433493
434494### min
@@ -472,6 +532,18 @@ const mm = lo.minMax(i32, &.{ 5, 1, 9, 3 }).?;
472532// mm.min_val == 1, mm.max_val == 9
473533```
474534
535+ ### minMaxBy
536+
537+ Returns both min and max in a single pass according to a custom comparator. Null if empty.
538+
539+ ``` zig
540+ const byX = struct { fn f(a: Point, b: Point) std.math.Order {
541+ return std.math.order(a.x, b.x);
542+ } }.f;
543+ const mm = lo.minMaxBy(Point, &points, byX).?;
544+ // mm.min_val and mm.max_val
545+ ```
546+
475547### count
476548
477549Count elements satisfying the predicate.
@@ -535,6 +607,22 @@ Standard deviation (sqrt of population variance). Returns null for empty slices.
535607lo.stddev(i32, &.{ 2, 4, 4, 4, 5, 5, 7, 9 }); // 2.0
536608```
537609
610+ ### sampleVariance
611+
612+ Sample variance with N-1 denominator (Bessel's correction). Returns null for slices with fewer than 2 elements.
613+
614+ ``` zig
615+ lo.sampleVariance(i32, &.{ 2, 4, 4, 4, 5, 5, 7, 9 }); // ~4.571
616+ ```
617+
618+ ### sampleStddev
619+
620+ Sample standard deviation (sqrt of sample variance). Returns null for slices with fewer than 2 elements.
621+
622+ ``` zig
623+ lo.sampleStddev(i32, &.{ 2, 4, 4, 4, 5, 5, 7, 9 }); // ~2.138
624+ ```
625+
538626### percentile
539627
540628Returns the nth percentile using linear interpolation. Null for empty slices or if p is outside [ 0, 100] .
@@ -729,6 +817,37 @@ try lo.elementsMatch(i32, allocator, &.{ 1, 2, 3 }, &.{ 3, 2, 1 }); // true
729817try lo.elementsMatch(i32, allocator, &.{ 1, 1, 2 }, &.{ 1, 2, 2 }); // false
730818```
731819
820+ ### differenceWith
821+
822+ Elements in the first slice but not in the second, using a custom equality predicate.
823+
824+ ``` zig
825+ const absEq = struct { fn f(a: i32, b: i32) bool { return @abs(a) == @abs(b); } }.f;
826+ const d = try lo.differenceWith(i32, allocator, &.{ 1, 2, 3 }, &.{ -2, 4 }, absEq);
827+ defer allocator.free(d);
828+ // d == &.{ 1, 3 }
829+ ```
830+
831+ ### intersectWith
832+
833+ Elements present in both slices, using a custom equality predicate.
834+
835+ ``` zig
836+ const i = try lo.intersectWith(i32, allocator, &.{ 1, -2, 3 }, &.{ 2, 4 }, absEq);
837+ defer allocator.free(i);
838+ // i == &.{ -2 }
839+ ```
840+
841+ ### unionWith
842+
843+ Unique elements from both slices combined, using a custom equality predicate.
844+
845+ ``` zig
846+ const u = try lo.unionWith(i32, allocator, &.{ 1, 2 }, &.{ -2, 3 }, absEq);
847+ defer allocator.free(u);
848+ // u == &.{ 1, 2, 3 }
849+ ```
850+
732851---
733852
734853## Partition & Group
@@ -1005,6 +1124,51 @@ Returns the index of the maximum element, or null if empty. First occurrence on
10051124lo.maxIndex(i32, &.{ 3, 1, 4, 1, 5 }); // 4
10061125```
10071126
1127+ ### binarySearch
1128+
1129+ Binary search for a target in a sorted ascending slice. Returns the index or null. O(log n).
1130+
1131+ ``` zig
1132+ lo.binarySearch(i32, &.{ 1, 3, 5, 7, 9 }, 5); // Some(2)
1133+ lo.binarySearch(i32, &.{ 1, 3, 5, 7, 9 }, 4); // null
1134+ ```
1135+
1136+ ### lowerBound
1137+
1138+ Index of the first element >= target in a sorted slice. Returns ` slice.len ` if all are less.
1139+
1140+ ``` zig
1141+ lo.lowerBound(i32, &.{ 1, 3, 5, 7 }, 4); // 2
1142+ lo.lowerBound(i32, &.{ 1, 3, 5, 7 }, 5); // 2
1143+ lo.lowerBound(i32, &.{ 1, 3, 5, 7 }, 9); // 4
1144+ ```
1145+
1146+ ### upperBound
1147+
1148+ Index of the first element > target in a sorted slice. Returns ` slice.len ` if all are <= target.
1149+
1150+ ``` zig
1151+ lo.upperBound(i32, &.{ 1, 3, 5, 7 }, 3); // 2
1152+ lo.upperBound(i32, &.{ 1, 3, 5, 7 }, 4); // 2
1153+ lo.upperBound(i32, &.{ 1, 3, 5, 7 }, 9); // 4
1154+ ```
1155+
1156+ ### sortedIndex
1157+
1158+ Insertion index to maintain sorted order. Equivalent to ` lowerBound ` .
1159+
1160+ ``` zig
1161+ lo.sortedIndex(i32, &.{ 1, 3, 5, 7 }, 4); // 2
1162+ ```
1163+
1164+ ### sortedLastIndex
1165+
1166+ Insertion index after the last occurrence of a value. Equivalent to ` upperBound ` .
1167+
1168+ ``` zig
1169+ lo.sortedLastIndex(i32, &.{ 1, 3, 3, 5 }, 3); // 3
1170+ ```
1171+
10081172---
10091173
10101174## Map Helpers
@@ -1123,7 +1287,7 @@ defer result.deinit();
11231287Keep only entries with the specified keys. Caller owns the returned map.
11241288
11251289``` zig
1126- var result = try lo.pickKeys(u32, u8, allocator, m, &.{ 1, 3 });
1290+ var result = try lo.pickKeys(u32, u8, allocator, & m, &.{ 1, 3 });
11271291defer result.deinit();
11281292```
11291293
@@ -1185,23 +1349,23 @@ defer allocator.free(result);
11851349Get a value from the map, or return a default if the key is absent.
11861350
11871351``` zig
1188- lo.valueOr(u32, u8, my_map, 999, 0); // 0 if 999 not in map
1352+ lo.valueOr(u32, u8, & my_map, 999, 0); // 0 if 999 not in map
11891353```
11901354
11911355### hasKey
11921356
11931357True if the map contains the given key.
11941358
11951359``` zig
1196- lo.hasKey(u32, u8, m, 1); // true
1360+ lo.hasKey(u32, u8, & m, 1); // true
11971361```
11981362
11991363### mapCount
12001364
12011365Number of entries in the map.
12021366
12031367``` zig
1204- lo.mapCount(u32, u8, m); // 3
1368+ lo.mapCount(u32, u8, & m); // 3
12051369```
12061370
12071371### keyBy
@@ -1517,10 +1681,10 @@ lo.sum(i32, &.{ 1, 2, 3, 4 }); // 10
15171681
15181682### mean
15191683
1520- Arithmetic mean. Returns 0.0 for empty slices.
1684+ Arithmetic mean. Returns null for empty slices.
15211685
15221686``` zig
1523- lo.mean(i32, &.{ 2, 4, 6 }); // 4.0
1687+ lo.mean(i32, &.{ 2, 4, 6 }).? ; // 4.0
15241688```
15251689
15261690### median
@@ -1548,6 +1712,22 @@ Standard deviation (sqrt of population variance). Null for empty slices.
15481712lo.stddev(i32, &.{ 2, 4, 4, 4, 5, 5, 7, 9 }); // 2.0
15491713```
15501714
1715+ ### sampleVariance
1716+
1717+ Sample variance with N-1 denominator (Bessel's correction). Null for slices with fewer than 2 elements.
1718+
1719+ ``` zig
1720+ lo.sampleVariance(i32, &.{ 2, 4, 4, 4, 5, 5, 7, 9 }); // ~4.571
1721+ ```
1722+
1723+ ### sampleStddev
1724+
1725+ Sample standard deviation (sqrt of sample variance). Null for slices with fewer than 2 elements.
1726+
1727+ ``` zig
1728+ lo.sampleStddev(i32, &.{ 2, 4, 4, 4, 5, 5, 7, 9 }); // ~2.138
1729+ ```
1730+
15511731### percentile
15521732
15531733Nth percentile using linear interpolation. Null for empty slices or p outside [ 0, 100] .
@@ -1828,6 +2008,7 @@ The following iterator types are returned by their corresponding functions. They
18282008| ` FlatMapIterator ` | ` flatMap() ` |
18292009| ` CompactIterator ` | ` compact() ` |
18302010| ` ChunkIterator ` | ` chunk() ` |
2011+ | ` FilterMapIterator ` | ` filterMapIter() ` |
18312012| ` WithoutIterator ` | ` without() ` |
18322013| ` ScanIterator ` | ` scan() ` |
18332014| ` WindowIterator ` | ` window() ` |
0 commit comments