github.com/mitranim/gg@v0.1.17/slice.go (about) 1 package gg 2 3 import ( 4 "sort" 5 ) 6 7 /* 8 Syntactic shortcut for creating a slice out of the given values. Simply returns 9 the slice of arguments as-is. Sometimes allows shorter code. Note that when 10 calling this function with an existing slice, you get the EXACT same slice 11 back, with no allocation. Also see `SliceOf` which returns `Slice[A]` rather 12 than `[]A`. 13 */ 14 func ToSlice[A any](val ...A) []A { return val } 15 16 /* 17 Syntactic shortcut for making `Slice[A]` out of the given values. Can also be 18 used to perform a free type conversion from an existing slice, with no 19 allocation. Also see `ToSlice` which returns `[]A` rather than `Slice[A]`. 20 */ 21 func SliceOf[A any](val ...A) Slice[A] { return Slice[A](val) } 22 23 /* 24 Shortcut for converting an arbitrary number of slices to `Slice[Elem]`. When 25 called with exactly one argument, this performs a free type conversion without 26 an allocation. When called with 2 or more arguments, this concatenates the 27 inputs, allocating a new slice. 28 */ 29 func SliceFrom[Src ~[]Elem, Elem any](src ...Src) Slice[Elem] { 30 switch len(src) { 31 case 0: 32 return nil 33 case 1: 34 return Slice[Elem](src[0]) 35 default: 36 return Slice[Elem](Concat(src...)) 37 } 38 } 39 40 /* 41 Typedef of an arbitrary slice with various methods that duplicate global slice 42 functions such as `Get` or `Filter`. Useful as a shortcut for creating bound 43 methods that can be passed to higher-order functions. Example: 44 45 values := []string{`one`, `two`, `three`} 46 indexes := []int{0, 2} 47 result := Map(indexes, SliceOf(values...).Get) 48 fmt.Println(grepr.String(result)) 49 // []string{`one`, `three`} 50 */ 51 type Slice[A any] []A 52 53 // True if len <= 0. Inverse of `.IsNotEmpty`. 54 func IsEmpty[Slice ~[]Elem, Elem any](val Slice) bool { return len(val) <= 0 } 55 56 // Same as global `IsEmpty`. 57 func (self Slice[_]) IsEmpty() bool { return IsEmpty(self) } 58 59 // True if len > 0. Inverse of `.IsEmpty`. 60 func IsNotEmpty[Slice ~[]Elem, Elem any](val Slice) bool { return len(val) > 0 } 61 62 // Same as global `IsNotEmpty`. 63 func (self Slice[_]) IsNotEmpty() bool { return IsNotEmpty(self) } 64 65 // Same as `len(val)` but can be passed to higher-order functions. 66 func Len[Slice ~[]Elem, Elem any](val Slice) int { return len(val) } 67 68 // Same as global `Len`. 69 func (self Slice[_]) Len() int { return len(self) } 70 71 // Same as `len(PtrGet(val))` but can be passed to higher-order functions. 72 func PtrLen[Slice ~[]Elem, Elem any](val *Slice) int { return len(PtrGet(val)) } 73 74 // Same as global `PtrLen`. 75 func (self *Slice[_]) PtrLen() int { return PtrLen(self) } 76 77 // Same as `cap(val)` but can be passed to higher-order functions. 78 func Cap[Slice ~[]Elem, Elem any](val Slice) int { return cap(val) } 79 80 // Same as global `Cap`. 81 func (self Slice[_]) Cap() int { return cap(self) } 82 83 // Amount of unused capacity in the given slice. 84 func CapUnused[Slice ~[]Elem, Elem any](src Slice) int { return cap(src) - len(src) } 85 86 // Same as global `CapUnused`. 87 func (self Slice[_]) CapUnused() int { return CapUnused(self) } 88 89 /* 90 Amount of missing capacity that needs to be allocated to append the given amount 91 of additional elements. 92 */ 93 func CapMissing[Slice ~[]Elem, Elem any](src Slice, size int) int { 94 return MaxPrim2(0, size-CapUnused(src)) 95 } 96 97 // Same as global `CapMissing`. 98 func (self Slice[_]) CapMissing(size int) int { return CapMissing(self, size) } 99 100 // Counts the total length of the given slices. 101 func Lens[Slice ~[]Elem, Elem any](val ...Slice) int { return Sum(val, Len[Slice]) } 102 103 // Grows the length of the given slice by appending N zero values. 104 func GrowLen[Slice ~[]Elem, Elem any](src Slice, size int) Slice { 105 return append(src, make(Slice, size)...) 106 } 107 108 // Same as global `GrowLen`. 109 func (self Slice[A]) GrowLen(size int) Slice[A] { return GrowLen(self, size) } 110 111 /* 112 Missing feature of the language / standard library. Ensures at least this much 113 unused capacity (not total capacity). If there is already enough capacity, 114 returns the slice as-is. Otherwise allocates a new slice, doubling the capacity 115 as many times as needed until it accommodates enough elements. Use this when 116 further growth is expected. When further growth is not expected, use 117 `GrowCapExact` instead. Similar to `(*bytes.Buffer).Grow` but works for all 118 slice types and avoids any wrapping, unwrapping, or spurious escapes to the 119 heap. 120 */ 121 func GrowCap[Slice ~[]Elem, Elem any](src Slice, size int) Slice { 122 missing := CapMissing(src, size) 123 if !(missing > 0) { 124 return src 125 } 126 127 prev := MaxPrim2(0, cap(src)) 128 next := Or(prev, 1) 129 for next < prev+size { 130 next *= 2 131 } 132 133 out := make(Slice, len(src), next) 134 copy(out, src) 135 return out 136 } 137 138 // Same as global `GrowCap`. 139 func (self Slice[A]) GrowCap(size int) Slice[A] { return GrowCap(self, size) } 140 141 /* 142 Missing feature of the language / standard library. Ensures at least this much 143 unused capacity (not total capacity). If there is already enough capacity, 144 returns the slice as-is. Otherwise allocates a new slice with EXACTLY enough 145 additional capacity. Use this when further growth is not expected. When further 146 growth is expected, use `GrowCap` instead. 147 */ 148 func GrowCapExact[Slice ~[]Elem, Elem any](src Slice, size int) Slice { 149 missing := CapMissing(src, size) 150 if !(missing > 0) { 151 return src 152 } 153 154 out := make(Slice, len(src), cap(src)+missing) 155 copy(out, src) 156 return out 157 } 158 159 // Same as global `GrowCapExact`. 160 func (self Slice[A]) GrowCapExact(size int) Slice[A] { return GrowCapExact(self, size) } 161 162 /* 163 Returns a modified slice where length is reduced to the given size. Negative 164 size is equivalent to zero. If the current length is already shorter, it's 165 unaffected. 166 */ 167 func TruncLen[Slice ~[]Elem, Elem any](src Slice, size int) Slice { 168 if size < len(src) { 169 if size < 0 { 170 return src[:0] 171 } 172 return src[:size] 173 } 174 return src 175 } 176 177 // Same as global `TruncLen`. 178 func (self Slice[A]) TruncLen(size int) Slice[A] { return TruncLen(self, size) } 179 180 // Zeroes each element of the given slice. 181 func SliceZero[A any](val []A) { 182 var zero A 183 for ind := range val { 184 val[ind] = zero 185 } 186 } 187 188 // Same as global `SliceZero`. 189 func (self Slice[_]) Zero() { SliceZero(self) } 190 191 /* 192 Collapses the slice's length, preserving the capacity. Does not modify any 193 elements. If the pointer is nil, does nothing. 194 */ 195 func Trunc[Slice ~[]Elem, Elem any](ptr *Slice) { 196 if ptr == nil { 197 return 198 } 199 tar := *ptr 200 if tar != nil { 201 *ptr = tar[:0] 202 } 203 } 204 205 // Same as global `Trunc`. 206 func (self *Slice[_]) Trunc() { Trunc(self) } 207 208 /* 209 If the index is within bounds, returns the value at that index and true. 210 Otherwise returns zero value and false. 211 */ 212 func Got[A any](src []A, ind int) (A, bool) { 213 if ind >= 0 && ind < len(src) { 214 return src[ind], true 215 } 216 return Zero[A](), false 217 } 218 219 // Same as global `Got`. 220 func (self Slice[A]) Got(ind int) (A, bool) { return Got(self, ind) } 221 222 /* 223 If the index is within bounds, returns the value at that index. 224 Otherwise returns zero value. 225 */ 226 func Get[A any](src []A, ind int) A { 227 if ind >= 0 && ind < len(src) { 228 return src[ind] 229 } 230 return Zero[A]() 231 } 232 233 // Same as global `Get`. 234 func (self Slice[A]) Get(ind int) A { return Get(self, ind) } 235 236 /* 237 If the index is within bounds, returns a pointer to the value at that index. 238 Otherwise returns nil. 239 */ 240 func GetPtr[A any](src []A, ind int) *A { 241 if ind >= 0 && ind < len(src) { 242 return &src[ind] 243 } 244 return nil 245 } 246 247 // Same as global `GetPtr`. 248 func (self Slice[A]) GetPtr(ind int) *A { return GetPtr(self, ind) } 249 250 /* 251 Sets a value at an index, same as by using the built-in square bracket syntax. 252 Useful as a shortcut for inline bound functions. 253 */ 254 func (self Slice[A]) Set(ind int, val A) { self[ind] = val } 255 256 /* 257 Returns a shallow copy of the given slice. The capacity of the resulting slice 258 is equal to its length. 259 */ 260 func Clone[Slice ~[]Elem, Elem any](src Slice) Slice { 261 if src == nil { 262 return nil 263 } 264 265 out := make(Slice, len(src)) 266 copy(out, src) 267 return out 268 } 269 270 // Same as global `Clone`. 271 func (self Slice[A]) Clone() Slice[A] { return Clone(self) } 272 273 /* 274 Same as `append`, but makes a copy instead of mutating the original. 275 Useful when reusing one "base" slice for in multiple append calls. 276 */ 277 func CloneAppend[Slice ~[]Elem, Elem any](src Slice, val ...Elem) Slice { 278 if src == nil && val == nil { 279 return nil 280 } 281 282 out := make(Slice, 0, len(src)+len(val)) 283 out = append(out, src...) 284 out = append(out, val...) 285 return out 286 } 287 288 // Same as global `CloneAppend`. 289 func (self Slice[A]) CloneAppend(val ...A) Slice[A] { 290 return CloneAppend(self, val...) 291 } 292 293 /* 294 Appends the given elements to the given slice. Similar to built-in `append` but 295 syntactically shorter. 296 */ 297 func Append[Slice ~[]Elem, Elem any](ptr *Slice, val ...Elem) { 298 if ptr != nil { 299 *ptr = append(*ptr, val...) 300 } 301 } 302 303 // Same as global `Append`. 304 func (self *Slice[A]) Append(val ...A) { Append(self, val...) } 305 306 /* 307 If the target pointer is nil, does nothing and returns -1. Otherwise appends the 308 given element to the given slice (like `Append`) and returns the last index 309 of the resulting slice. Also see `AppendPtr`. 310 */ 311 func AppendIndex[Slice ~[]Elem, Elem any](ptr *Slice, val Elem) int { 312 if ptr == nil { 313 return -1 314 } 315 316 tar := *ptr 317 tar = append(tar, val) 318 *ptr = tar 319 return LastIndex(tar) 320 } 321 322 // Same as global `AppendIndex`. 323 func (self *Slice[A]) AppendIndex(val A) int { return AppendIndex(self, val) } 324 325 /* 326 Appends the given element to the given slice, returning the pointer to the newly 327 appended position in the slice. If the target pointer is nil, does nothing and 328 returns nil. Also see `AppendIndex`. 329 */ 330 func AppendPtr[Slice ~[]Elem, Elem any](ptr *Slice, val Elem) *Elem { 331 if ptr == nil { 332 return nil 333 } 334 335 tar := append(*ptr, val) 336 *ptr = tar 337 return LastPtr(tar) 338 } 339 340 // Same as global `AppendPtr`. 341 func (self *Slice[A]) AppendPtr(val A) *A { return AppendPtr(self, val) } 342 343 /* 344 Appends a zero element to the given slice, returning the pointer to the newly 345 appended position in the slice. If the target pointer is nil, does nothing and 346 returns nil. 347 */ 348 func AppendPtrZero[Slice ~[]Elem, Elem any](ptr *Slice) *Elem { 349 return AppendPtr(ptr, Zero[Elem]()) 350 } 351 352 // Same as global `AppendPtrZero`. 353 func (self *Slice[A]) AppendPtrZero() *A { return AppendPtrZero(self) } 354 355 /* 356 Returns the first element of the given slice. If the slice is empty, returns the 357 zero value. 358 */ 359 func Head[Slice ~[]Elem, Elem any](val Slice) Elem { return Get(val, 0) } 360 361 // Same as global `Head`. 362 func (self Slice[A]) Head() A { return Head(self) } 363 364 /* 365 Returns a pointer to the first element of the given slice. If the slice is 366 empty, the pointer is nil. 367 */ 368 func HeadPtr[Slice ~[]Elem, Elem any](val Slice) *Elem { return GetPtr(val, 0) } 369 370 // Same as global `HeadPtr`. 371 func (self Slice[A]) HeadPtr() *A { return HeadPtr(self) } 372 373 func PopHead[Slice ~[]Elem, Elem any](ptr *Slice) Elem { 374 if ptr == nil { 375 return Zero[Elem]() 376 } 377 378 head, tail := Head(*ptr), Tail(*ptr) 379 *ptr = tail 380 return head 381 } 382 383 // Same as global `PopHead`. 384 func (self *Slice[A]) PopHead() A { return PopHead(self) } 385 386 /* 387 Returns the last element of the given slice. If the slice is empty, returns the 388 zero value. 389 */ 390 func Last[Slice ~[]Elem, Elem any](val Slice) Elem { return Get(val, len(val)-1) } 391 392 // Same as global `Last`. 393 func (self Slice[A]) Last() A { return Last(self) } 394 395 /* 396 Returns a pointer to the last element of the given slice. If the slice is empty, 397 the pointer is nil. 398 */ 399 func LastPtr[Slice ~[]Elem, Elem any](val Slice) *Elem { return GetPtr(val, len(val)-1) } 400 401 // Same as global `LastPtr`. 402 func (self Slice[A]) LastPtr() *A { return LastPtr(self) } 403 404 /* 405 Returns the index of the last element of the given slice. 406 Same as `len(val)-1`. If slice is empty, returns -1. 407 */ 408 func LastIndex[Slice ~[]Elem, Elem any](val Slice) int { return len(val) - 1 } 409 410 // Same as global `LastIndex`. 411 func (self Slice[A]) LastIndex() int { return LastIndex(self) } 412 413 func PopLast[Slice ~[]Elem, Elem any](ptr *Slice) Elem { 414 if ptr == nil { 415 return Zero[Elem]() 416 } 417 418 init, last := Init(*ptr), Last(*ptr) 419 *ptr = init 420 return last 421 } 422 423 // Same as global `PopLast`. 424 func (self *Slice[A]) PopLast() A { return PopLast(self) } 425 426 /* 427 Returns the initial part of the given slice: all except the last value. 428 If the slice is nil, returns nil. 429 */ 430 func Init[Slice ~[]Elem, Elem any](val Slice) Slice { 431 if len(val) <= 0 { 432 return val 433 } 434 return val[:len(val)-1] 435 } 436 437 // Same as global `Init`. 438 func (self Slice[A]) Init() Slice[A] { return Init(self) } 439 440 /* 441 Returns the tail part of the given slice: all except the first value. 442 If the slice is nil, returns nil. 443 */ 444 func Tail[Slice ~[]Elem, Elem any](val Slice) Slice { 445 if len(val) <= 0 { 446 return val 447 } 448 return val[1:] 449 } 450 451 // Same as global `Tail`. 452 func (self Slice[A]) Tail() Slice[A] { return Tail(self) } 453 454 // Returns a subslice containing N elements from the start. 455 func Take[Slice ~[]Elem, Elem any](src Slice, size int) Slice { 456 return src[:MaxPrim2(0, MinPrim2(size, len(src)))] 457 } 458 459 // Same as global `Take`. 460 func (self Slice[A]) Take(size int) Slice[A] { return Take(self, size) } 461 462 // Returns a subslice excluding N elements from the start. 463 func Drop[Slice ~[]Elem, Elem any](src Slice, size int) Slice { 464 return src[MaxPrim2(0, MinPrim2(size, len(src))):] 465 } 466 467 // Same as global `Drop`. 468 func (self Slice[A]) Drop(size int) Slice[A] { return Drop(self, size) } 469 470 /* 471 Returns a subslice containing only elements at the start of the slice 472 for which the given function contiguously returned `true`. 473 */ 474 func TakeWhile[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) Slice { 475 return Take(src, 1+FindIndex(src, func(val Elem) bool { return !fun(val) })) 476 } 477 478 // Same as global `TakeWhile`. 479 func (self Slice[A]) TakeWhile(fun func(A) bool) Slice[A] { 480 return TakeWhile(self, fun) 481 } 482 483 /* 484 Returns a subslice excluding elements at the start of the slice 485 for which the given function contiguously returned `true`. 486 */ 487 func DropWhile[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) Slice { 488 return Drop(src, 1+FindIndex(src, fun)) 489 } 490 491 // Same as global `DropWhile`. 492 func (self Slice[A]) DropWhile(fun func(A) bool) Slice[A] { 493 return DropWhile(self, fun) 494 } 495 496 // Calls the given function for each element of the given slice. 497 func Each[Slice ~[]Elem, Elem any](val Slice, fun func(Elem)) { 498 if fun != nil { 499 for _, val := range val { 500 fun(val) 501 } 502 } 503 } 504 505 // Same as global `Each`. 506 func (self Slice[A]) Each(val Slice[A], fun func(A)) { Each(self, fun) } 507 508 /* 509 Calls the given function for each element's pointer in the given slice. 510 The pointer is always non-nil. 511 */ 512 func EachPtr[Slice ~[]Elem, Elem any](val Slice, fun func(*Elem)) { 513 if fun != nil { 514 for ind := range val { 515 fun(&val[ind]) 516 } 517 } 518 } 519 520 // Same as global `EachPtr`. 521 func (self Slice[A]) EachPtr(fun func(*A)) { EachPtr(self, fun) } 522 523 /* 524 Similar to `Each` but iterates two slices pairwise. If slice lengths don't 525 match, panics. 526 */ 527 func Each2[A, B any](one []A, two []B, fun func(A, B)) { 528 validateLenMatch(len(one), len(two)) 529 530 if fun != nil { 531 for ind := range one { 532 fun(one[ind], two[ind]) 533 } 534 } 535 } 536 537 /* 538 Returns the smallest value from among the inputs, which must be comparable 539 primitives. For non-primitives, see `Min`. 540 */ 541 func MinPrim[A LesserPrim](val ...A) A { return Fold1(val, MinPrim2[A]) } 542 543 /* 544 Returns the largest value from among the inputs, which must be comparable 545 primitives. For non-primitives, see `Max`. 546 */ 547 func MaxPrim[A LesserPrim](val ...A) A { return Fold1(val, MaxPrim2[A]) } 548 549 /* 550 Returns the smallest value from among the inputs. For primitive types that don't 551 implement `Lesser`, see `MinPrim`. 552 */ 553 func Min[A Lesser[A]](val ...A) A { return Fold1(val, Min2[A]) } 554 555 /* 556 Returns the largest value from among the inputs. For primitive types that don't 557 implement `Lesser`, see `MaxPrim`. 558 */ 559 func Max[A Lesser[A]](val ...A) A { return Fold1(val, Max2[A]) } 560 561 /* 562 Calls the given function for each element of the given slice and returns the 563 smallest value from among the results, which must be comparable primitives. 564 For non-primitives, see `MinBy`. 565 */ 566 func MinPrimBy[Src any, Out LesserPrim](src []Src, fun func(Src) Out) Out { 567 if len(src) <= 0 || fun == nil { 568 return Zero[Out]() 569 } 570 571 return Fold(src[1:], fun(src[0]), func(acc Out, src Src) Out { 572 return MinPrim2(acc, fun(src)) 573 }) 574 } 575 576 /* 577 Calls the given function for each element of the given slice and returns the 578 smallest value from among the results. For primitive types that don't implement 579 `Lesser`, see `MinPrimBy`. 580 */ 581 func MinBy[Src any, Out Lesser[Out]](src []Src, fun func(Src) Out) Out { 582 if len(src) <= 0 || fun == nil { 583 return Zero[Out]() 584 } 585 586 return Fold(src[1:], fun(src[0]), func(acc Out, src Src) Out { 587 return Min2(acc, fun(src)) 588 }) 589 } 590 591 /* 592 Calls the given function for each element of the given slice and returns the 593 largest value from among the results, which must be comparable primitives. 594 For non-primitives, see `MaxBy`. 595 */ 596 func MaxPrimBy[Src any, Out LesserPrim](src []Src, fun func(Src) Out) Out { 597 if len(src) <= 0 || fun == nil { 598 return Zero[Out]() 599 } 600 601 return Fold(src[1:], fun(src[0]), func(acc Out, src Src) Out { 602 return MaxPrim2(acc, fun(src)) 603 }) 604 } 605 606 /* 607 Calls the given function for each element of the given slice and returns the 608 largest value from among the results. For primitive types that don't implement 609 `Lesser`, see `MaxPrimBy`. 610 */ 611 func MaxBy[Src any, Out Lesser[Out]](src []Src, fun func(Src) Out) Out { 612 if len(src) <= 0 || fun == nil { 613 return Zero[Out]() 614 } 615 616 return Fold(src[1:], fun(src[0]), func(acc Out, src Src) Out { 617 return Max2(acc, fun(src)) 618 }) 619 } 620 621 /* 622 Calls the given function on each element of the given slice and returns the sum 623 of all results, combined via `+`. 624 */ 625 func Sum[Src any, Out Plusable](src []Src, fun func(Src) Out) Out { 626 if fun == nil { 627 return Zero[Out]() 628 } 629 return Foldz(src, func(acc Out, src Src) Out { return acc + fun(src) }) 630 } 631 632 /* 633 Counts occurrences elements of the given slice, keyed by calling the given 634 function for each element, and returning the resulting map. If the function is 635 nil, returns nil. Compare `Group` which returns `map[Key][]Val` rather than 636 `map[Key]int`, and `Index` which returns `map[Key]Val`. 637 */ 638 func Counts[Slice ~[]Val, Key comparable, Val any](src Slice, fun func(Val) Key) map[Key]int { 639 if fun == nil { 640 return nil 641 } 642 643 out := map[Key]int{} 644 CountsInto(out, src, fun) 645 return out 646 } 647 648 /* 649 Counts occurrences elements of the given slice, keyed by calling the given 650 function for each element, modifying the given map, which must be non-nil if 651 the slice is non-empty. If the function is nil, does nothing. 652 */ 653 func CountsInto[Key comparable, Val any](tar map[Key]int, src []Val, fun func(Val) Key) { 654 if fun == nil { 655 return 656 } 657 for _, val := range src { 658 tar[fun(val)]++ 659 } 660 } 661 662 /* 663 Maps one slice to another. The resulting slice has exactly the same length as 664 the original. Each element is created by calling the given function on the 665 corresponding element of the original slice. The name refers to a well-known 666 functional programming abstraction which doesn't have anything in common with 667 the Go `map` types. Unlike many other higher-order slice functions, this one 668 requires a non-nil function. 669 */ 670 func Map[A, B any](src []A, fun func(A) B) []B { 671 if src == nil { 672 return nil 673 } 674 675 out := make([]B, 0, len(src)) 676 for _, val := range src { 677 out = append(out, fun(val)) 678 } 679 return out 680 } 681 682 /* 683 Similar to `Map` but instead of creating a new slice, appends to an existing 684 slice. 685 */ 686 func MapAppend[ 687 Src ~[]SrcVal, 688 Tar ~[]TarVal, 689 SrcVal any, 690 TarVal any, 691 ](ptr *Tar, src Src, fun func(SrcVal) TarVal) { 692 if ptr == nil || fun == nil { 693 return 694 } 695 696 tar := GrowCap(*ptr, len(src)) 697 for _, val := range src { 698 tar = append(tar, fun(val)) 699 } 700 *ptr = tar 701 } 702 703 /* 704 Similar to `Map`, but instead of creating a new slice, mutates the old one in 705 place by calling the given function on each element. 706 */ 707 func MapMut[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) Elem) Slice { 708 if fun != nil { 709 for ind := range src { 710 src[ind] = fun(src[ind]) 711 } 712 } 713 return src 714 } 715 716 // Same as global `MapMut`. 717 func (self Slice[A]) MapMut(fun func(A) A) Slice[A] { return MapMut(self, fun) } 718 719 /* 720 Similar to `Map`, but calls the given function on each element pointer, rather 721 than on each element. Every pointer is non-nil. 722 */ 723 func MapPtr[A, B any](src []A, fun func(*A) B) []B { 724 if src == nil { 725 return nil 726 } 727 728 out := make([]B, 0, len(src)) 729 for ind := range src { 730 out = append(out, fun(&src[ind])) 731 } 732 return out 733 } 734 735 /* 736 Similar to `Map` but iterates two slices pairwise, passing each element pair to 737 the mapping function. If slice lengths don't match, panics. 738 */ 739 func Map2[A, B, C any](one []A, two []B, fun func(A, B) C) []C { 740 validateLenMatch(len(one), len(two)) 741 742 if one == nil || two == nil { 743 return nil 744 } 745 746 out := make([]C, 0, len(one)) 747 for ind := range one { 748 out = append(out, fun(one[ind], two[ind])) 749 } 750 return out 751 } 752 753 // Similar to `Map` but excludes any zero values produced by the given function. 754 func MapCompact[A, B any](src []A, fun func(A) B) []B { 755 if fun == nil { 756 return nil 757 } 758 759 var out []B 760 for _, val := range src { 761 val := fun(val) 762 if !IsZero(val) { 763 out = append(out, val) 764 } 765 } 766 return out 767 } 768 769 // Similar to `Map` but concats the slices returned by the given function. 770 func MapFlat[Out ~[]B, A, B any](src []A, fun func(A) Out) Out { 771 if src == nil { 772 return nil 773 } 774 775 var out Out 776 for _, val := range src { 777 out = append(out, fun(val)...) 778 } 779 return out 780 } 781 782 // Similar to `Map` but excludes duplicates. 783 func MapUniq[A any, B comparable](src []A, fun func(A) B) []B { 784 if src == nil { 785 return nil 786 } 787 788 switch len(src) { 789 case 0: 790 return []B{} 791 792 case 1: 793 return []B{fun(src[0])} 794 795 case 2: 796 one := fun(src[0]) 797 two := fun(src[1]) 798 if one == two { 799 return []B{one} 800 } 801 return []B{one, two} 802 803 default: 804 set := make(Set[B]) 805 out := make([]B, 0, len(src)) 806 for _, src := range src { 807 val := fun(src) 808 if set.Has(val) { 809 continue 810 } 811 set.Add(val) 812 out = append(out, val) 813 } 814 return out 815 } 816 } 817 818 // Similar to `MapFlat` but excludes duplicates. 819 func MapFlatUniq[Out ~[]B, A any, B comparable](src []A, fun func(A) Out) Out { 820 if src == nil { 821 return nil 822 } 823 824 var out Out 825 var set Set[B] 826 for _, src := range src { 827 for _, val := range fun(src) { 828 if set.Has(val) { 829 continue 830 } 831 set.Init().Add(val) 832 out = append(out, val) 833 } 834 } 835 return out 836 } 837 838 /* 839 Takes a slice and "indexes" it by using keys generated by the given function, 840 returning the resulting map. If the function is nil, returns nil. Compare 841 `Group` which returns `map[Key][]Val` rather than `map[Key]Val`. 842 */ 843 func Index[Slice ~[]Val, Key comparable, Val any](src Slice, fun func(Val) Key) map[Key]Val { 844 if fun == nil { 845 return nil 846 } 847 848 out := make(map[Key]Val, len(src)) 849 IndexInto(out, src, fun) 850 return out 851 } 852 853 /* 854 "Indexes" the given slice by adding its values to the given map, keyed by 855 calling the given function for each value. If the function is nil, does 856 nothing. 857 */ 858 func IndexInto[Key comparable, Val any](tar map[Key]Val, src []Val, fun func(Val) Key) { 859 if fun == nil { 860 return 861 } 862 for _, val := range src { 863 tar[fun(val)] = val 864 } 865 } 866 867 /* 868 Takes a slice and "indexes" it by converting each element to a key-value pair, 869 returning the resulting map. If the function is nil or the source slice is 870 empty, returns nil. 871 */ 872 func IndexPair[ 873 Slice ~[]Elem, 874 Elem any, 875 Key comparable, 876 Val any, 877 ]( 878 src Slice, fun func(Elem) (Key, Val), 879 ) map[Key]Val { 880 if fun == nil || len(src) <= 0 { 881 return nil 882 } 883 884 out := make(map[Key]Val, len(src)) 885 IndexPairInto(out, src, fun) 886 return out 887 } 888 889 /* 890 Takes a slice and "indexes" it by adding key-value pairs to the given map, 891 making key-value pairs by calling the given function for each element. If the 892 function is nil or the source slice is empty, does nothing. 893 */ 894 func IndexPairInto[Elem any, Key comparable, Val any]( 895 tar map[Key]Val, 896 src []Elem, 897 fun func(Elem) (Key, Val), 898 ) { 899 if fun == nil { 900 return 901 } 902 903 for _, src := range src { 904 key, val := fun(src) 905 tar[key] = val 906 } 907 } 908 909 /* 910 Groups the elements of the given slice by using keys generated by the given 911 function, returning the resulting map. If the function is nil, returns nil. 912 Compare `Index` which returns `map[Key]Val` rather than `map[Key][]Val`. 913 */ 914 func Group[Slice ~[]Val, Key comparable, Val any](src Slice, fun func(Val) Key) map[Key][]Val { 915 if fun == nil { 916 return nil 917 } 918 919 out := map[Key][]Val{} 920 GroupInto(out, src, fun) 921 return out 922 } 923 924 /* 925 Groups the elements of the given slice by adding its elements to slices in the 926 given map, keyed by calling the given function for each element. If the 927 function is nil, does nothing. 928 */ 929 func GroupInto[Key comparable, Val any](tar map[Key][]Val, src []Val, fun func(Val) Key) { 930 if fun == nil { 931 return 932 } 933 for _, val := range src { 934 key := fun(val) 935 tar[key] = append(tar[key], val) 936 } 937 } 938 939 /* 940 Somewhat similar to `Map`. Creates a slice by "mapping" source values to 941 outputs. Calls the given function N times, passing an index, starting with 0. 942 */ 943 func Times[A any](src int, fun func(int) A) []A { 944 if !(src > 0) || fun == nil { 945 return nil 946 } 947 948 buf := make([]A, src) 949 for ind := range buf { 950 buf[ind] = fun(ind) 951 } 952 return buf 953 } 954 955 /* 956 Similar to `Times` but instead of creating a new slice, appends to an existing 957 slice. 958 */ 959 func TimesAppend[Slice ~[]Elem, Elem any](ptr *Slice, src int, fun func(int) Elem) { 960 if ptr == nil || fun == nil || !(src > 0) { 961 return 962 } 963 964 tar := GrowCap(*ptr, src) 965 for ind := range Iter(src) { 966 tar = append(tar, fun(ind)) 967 } 968 *ptr = tar 969 } 970 971 // Same as global `TimesAppend`. 972 func (self *Slice[A]) TimesAppend(src int, fun func(int) A) { 973 TimesAppend(self, src, fun) 974 } 975 976 // Counts the number of elements for which the given function returns true. 977 func Count[A any](src []A, fun func(A) bool) int { 978 var out int 979 if fun != nil { 980 for _, src := range src { 981 if fun(src) { 982 out++ 983 } 984 } 985 } 986 return out 987 } 988 989 // Same as global `Count`. 990 func (self Slice[A]) Count(src []A, fun func(A) bool) int { return Count(self, fun) } 991 992 /* 993 Folds the given slice by calling the given function for each element, 994 additionally passing the "accumulator". Returns the resulting accumulator. 995 */ 996 func Fold[Acc, Val any](src []Val, acc Acc, fun func(Acc, Val) Acc) Acc { 997 if fun != nil { 998 for _, val := range src { 999 acc = fun(acc, val) 1000 } 1001 } 1002 return acc 1003 } 1004 1005 /* 1006 Short for "fold zero". Similar to `Fold` but the accumulator automatically 1007 starts as the zero value of its type. 1008 */ 1009 func Foldz[Acc, Val any](src []Val, fun func(Acc, Val) Acc) Acc { 1010 return Fold(src, Zero[Acc](), fun) 1011 } 1012 1013 /* 1014 Similar to `Fold` but uses the first slice element as the accumulator, falling 1015 back on zero value. The given function is invoked only for 2 or more elements. 1016 */ 1017 func Fold1[A any](src []A, fun func(A, A) A) A { 1018 if len(src) <= 0 { 1019 return Zero[A]() 1020 } 1021 return Fold(src[1:], src[0], fun) 1022 } 1023 1024 // Returns only the elements for which the given function returned `true`. 1025 func Filter[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) (out Slice) { 1026 FilterAppend(&out, src, fun) 1027 return 1028 } 1029 1030 // Same as global `Filter`. 1031 func (self Slice[A]) Filter(fun func(A) bool) Slice[A] { 1032 return Filter(self, fun) 1033 } 1034 1035 /* 1036 Similar to `Filter` but instead of creating a new slice, appends to an existing 1037 slice. 1038 */ 1039 func FilterAppend[Tar ~[]Elem, Elem any](ptr *Tar, src []Elem, fun func(Elem) bool) { 1040 if ptr == nil || fun == nil { 1041 return 1042 } 1043 1044 for _, val := range src { 1045 if fun(val) { 1046 *ptr = append(*ptr, val) 1047 } 1048 } 1049 } 1050 1051 // Same as global `FilterAppend`. 1052 func (self *Slice[A]) FilterAppend(src []A, fun func(A) bool) { 1053 FilterAppend(self, src, fun) 1054 } 1055 1056 /* 1057 Inverse of `Filter`. Returns only the elements for which the given function 1058 returned `false`. 1059 */ 1060 func Reject[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) (out Slice) { 1061 RejectAppend(&out, src, fun) 1062 return 1063 } 1064 1065 // Same as global `Reject`. 1066 func (self Slice[A]) Reject(fun func(A) bool) Slice[A] { 1067 return Reject(self, fun) 1068 } 1069 1070 /* 1071 Similar to `Reject` but instead of creating a new slice, appends to an existing 1072 slice. 1073 */ 1074 func RejectAppend[Tar ~[]Elem, Elem any](ptr *Tar, src []Elem, fun func(Elem) bool) { 1075 if ptr == nil || fun == nil { 1076 return 1077 } 1078 1079 for _, val := range src { 1080 if !fun(val) { 1081 *ptr = append(*ptr, val) 1082 } 1083 } 1084 } 1085 1086 // Same as global `RejectAppend`. 1087 func (self *Slice[A]) RejectAppend(src []A, fun func(A) bool) { 1088 RejectAppend(self, src, fun) 1089 } 1090 1091 /* 1092 Takes a slice and returns the indexes whose elements satisfy the given function. 1093 All indexes are within the bounds of the original slice. 1094 */ 1095 func FilterIndex[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) []int { 1096 if fun == nil { 1097 return nil 1098 } 1099 1100 var out []int 1101 for ind, val := range src { 1102 if fun(val) { 1103 out = append(out, ind) 1104 } 1105 } 1106 return out 1107 } 1108 1109 // Same as global `FilterIndex`. 1110 func (self Slice[A]) FilterIndex(fun func(A) bool) []int { 1111 return FilterIndex(self, fun) 1112 } 1113 1114 /* 1115 Takes a slice and returns the indexes whose elements are zero. 1116 All indexes are within the bounds of the original slice. 1117 */ 1118 func ZeroIndex[Slice ~[]Elem, Elem any](src Slice) []int { 1119 return FilterIndex(src, IsZero[Elem]) 1120 } 1121 1122 // Same as global `ZeroIndex`. 1123 func (self Slice[A]) ZeroIndex() []int { return ZeroIndex(self) } 1124 1125 /* 1126 Takes a slice and returns the indexes whose elements are non-zero. 1127 All indexes are within the bounds of the original slice. 1128 */ 1129 func NotZeroIndex[Slice ~[]Elem, Elem any](src Slice) []int { 1130 return FilterIndex(src, IsNotZero[Elem]) 1131 } 1132 1133 // Same as global `NotZeroIndex`. 1134 func (self Slice[A]) NotZeroIndex() []int { return NotZeroIndex(self) } 1135 1136 // Returns a version of the given slice without any zero values. 1137 func Compact[Slice ~[]Elem, Elem any](src Slice) Slice { 1138 return Filter(src, IsNotZero[Elem]) 1139 } 1140 1141 // Same as global `Compact`. 1142 func (self Slice[A]) Compact() Slice[A] { return Compact(self) } 1143 1144 /* 1145 Tests each element by calling the given function and returns the first element 1146 for which it returns `true`. If none match, returns `-1`. 1147 */ 1148 func FindIndex[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) int { 1149 if fun != nil { 1150 for ind, val := range src { 1151 if fun(val) { 1152 return ind 1153 } 1154 } 1155 } 1156 return -1 1157 } 1158 1159 // Same as global `FindIndex`. 1160 func (self Slice[A]) FindIndex(fun func(A) bool) int { 1161 return FindIndex(self, fun) 1162 } 1163 1164 /* 1165 Returns the first element for which the given function returns `true`. 1166 If nothing is found, returns a zero value. The additional boolean indicates 1167 whether something was actually found. 1168 */ 1169 func Found[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) (Elem, bool) { 1170 ind := FindIndex(src, fun) 1171 if ind >= 0 { 1172 return src[ind], true 1173 } 1174 return Zero[Elem](), false 1175 } 1176 1177 // Same as global `Found`. 1178 func (self Slice[A]) Found(fun func(A) bool) (A, bool) { 1179 return Found(self, fun) 1180 } 1181 1182 /* 1183 Returns the first element for which the given function returns true. 1184 If nothing is found, returns a zero value. 1185 */ 1186 func Find[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) Elem { 1187 return Get(src, FindIndex(src, fun)) 1188 } 1189 1190 // Same as global `Find`. 1191 func (self Slice[A]) Find(fun func(A) bool) A { return Find(self, fun) } 1192 1193 /* 1194 Similar to `Found`, but instead of returning an element, returns the first 1195 product of the given function for which the returned boolean is true. If 1196 nothing is procured, returns zero value and false. 1197 */ 1198 func Procured[Out, Src any](src []Src, fun func(Src) (Out, bool)) (Out, bool) { 1199 if fun != nil { 1200 for _, src := range src { 1201 val, ok := fun(src) 1202 if ok { 1203 return val, true 1204 } 1205 } 1206 } 1207 return Zero[Out](), false 1208 } 1209 1210 /* 1211 Similar to `Find`, but instead of returning the first approved element, 1212 returns the first non-zero result of the given function. If nothing is 1213 procured, returns a zero value. 1214 */ 1215 func Procure[Out, Src any](src []Src, fun func(Src) Out) Out { 1216 if fun != nil { 1217 for _, src := range src { 1218 val := fun(src) 1219 if IsNotZero(val) { 1220 return val 1221 } 1222 } 1223 } 1224 return Zero[Out]() 1225 } 1226 1227 /* 1228 Returns a version of the given slice with the given values appended unless they 1229 were already present in the slice. This function only appends; it doesn't 1230 deduplicate any previously existing values in the slice, nor reorder them. 1231 */ 1232 func Adjoin[Slice ~[]Elem, Elem comparable](tar Slice, src ...Elem) Slice { 1233 RejectAppend(&tar, src, SetOf(tar...).Has) 1234 return tar 1235 } 1236 1237 /* 1238 Returns a version of the given slice excluding any additionally supplied 1239 values. 1240 */ 1241 func Exclude[Slice ~[]Elem, Elem comparable](base Slice, sub ...Elem) Slice { 1242 return Reject(base, SetOf(sub...).Has) 1243 } 1244 1245 /* 1246 Returns a version of the given slice excluding any additionally supplied 1247 values. 1248 */ 1249 func ExcludeFrom[Slice ~[]Elem, Elem comparable](base Slice, sub ...Slice) Slice { 1250 return Reject(base, SetFrom(sub...).Has) 1251 } 1252 1253 // Returns intersection of two slices: elements that occur in both. 1254 func Intersect[Slice ~[]Elem, Elem comparable](one, two Slice) Slice { 1255 return Filter(one, SetOf(two...).Has) 1256 } 1257 1258 /* 1259 Combines the given slices, deduplicating their elements and preserving the order 1260 of first occurrence for each element. As a special case, if the arguments 1261 contain exactly one non-empty slice, it's returned as-is without deduplication. 1262 To ensure uniqueness in all cases, call `Uniq`. 1263 */ 1264 func Union[Slice ~[]Elem, Elem comparable](val ...Slice) Slice { 1265 if Count(val, IsNotEmpty[Slice]) == 1 { 1266 return Find(val, IsNotEmpty[Slice]) 1267 } 1268 1269 var tar Slice 1270 var set Set[Elem] 1271 1272 for _, val := range val { 1273 for _, val := range val { 1274 if set.Has(val) { 1275 continue 1276 } 1277 tar = append(tar, val) 1278 set.Init().Add(val) 1279 } 1280 } 1281 1282 return tar 1283 } 1284 1285 /* 1286 Deduplicates the elements of the given slice, preserving the order of initial 1287 occurrence for each element. The output is always either nil or a newly 1288 allocated slice with at least one element. Compare `UniqBy` which compares 1289 elements by keys obtained by calling the given function. 1290 */ 1291 func Uniq[Slice ~[]Elem, Elem comparable](src Slice) Slice { 1292 var tar Slice 1293 var set Set[Elem] 1294 1295 for _, val := range src { 1296 if set.Has(val) { 1297 continue 1298 } 1299 tar = append(tar, val) 1300 set.Init().Add(val) 1301 } 1302 1303 return tar 1304 } 1305 1306 /* 1307 Deduplicates the elements of the given slice on keys obtained by calling the 1308 given function for each element, and preserving the order of initial occurrence 1309 for each element. If the function is nil, returns nil. The output is always 1310 either nil or a newly allocated slice with at least one element. Compare `Uniq` 1311 which compares the elements themselves. 1312 */ 1313 func UniqBy[Slice ~[]Elem, Elem any, Key comparable](src Slice, fun func(Elem) Key) Slice { 1314 if fun == nil { 1315 return nil 1316 } 1317 1318 var tar Slice 1319 var set Set[Key] 1320 1321 for _, val := range src { 1322 key := fun(val) 1323 if set.Has(key) { 1324 continue 1325 } 1326 tar = append(tar, val) 1327 set.Init().Add(key) 1328 } 1329 1330 return tar 1331 } 1332 1333 /* 1334 Variant of `Has` that uses `Equal` rather than `==` to compare elements. Should 1335 be used ONLY for very small inputs: no more than a few tens of elements. For 1336 larger data, consider using indexed data structures such as sets and maps. 1337 */ 1338 func HasEqual[A any](src []A, val A) bool { 1339 return Some(src, func(elem A) bool { return Equal(elem, val) }) 1340 } 1341 1342 // Same as global `HasEqual`. 1343 func (self Slice[A]) HasEqual(val A) bool { return HasEqual(self, val) } 1344 1345 /* 1346 True if the given slice contains the given value. Should be used ONLY for very 1347 small inputs: no more than a few tens of elements. For larger data, consider 1348 using indexed data structures such as sets and maps. Inverse of `NotHas`. 1349 */ 1350 func Has[A comparable](src []A, val A) bool { 1351 return Some(src, func(elem A) bool { return elem == val }) 1352 } 1353 1354 /* 1355 True if the given slice does not contain the given value. Should be used ONLY 1356 for very small inputs: no more than a few tens of elements. For larger data, 1357 consider using indexed data structures such as sets and maps. Inverse of `Has`. 1358 The awkward name is chosen for symmetry with `gtest.NotHas` where it fits more 1359 naturally due to conventions for assertion naming. 1360 */ 1361 func NotHas[A comparable](src []A, val A) bool { return !Has(src, val) } 1362 1363 /* 1364 True if the first slice has all elements from the second slice. In other words, 1365 true if A is a superset of B: A >= B. 1366 */ 1367 func HasEvery[A comparable](src, exp []A) bool { 1368 return Every(exp, SetOf(src...).Has) 1369 } 1370 1371 /* 1372 True if the first slice has some elements from the second slice. In other words, 1373 true if the sets A and B intersect. 1374 */ 1375 func HasSome[A comparable](src, exp []A) bool { 1376 return Some(exp, SetOf(src...).Has) 1377 } 1378 1379 /* 1380 True if the first slice has NO elements from the second slice. In other words, 1381 true if the sets A and B don't intersect. 1382 */ 1383 func HasNone[A comparable](src, exp []A) bool { 1384 return None(exp, SetOf(src...).Has) 1385 } 1386 1387 /* 1388 True if the given function returns true for any element of the given slice. 1389 False if the function is nil. False if the slice is empty. 1390 */ 1391 func Some[A any](src []A, fun func(A) bool) bool { 1392 if fun == nil { 1393 return false 1394 } 1395 for _, val := range src { 1396 if fun(val) { 1397 return true 1398 } 1399 } 1400 return false 1401 } 1402 1403 // Same as global `Some`. 1404 func (self Slice[A]) Some(fun func(A) bool) bool { return Some(self, fun) } 1405 1406 /* 1407 True if the given function returns false for every element of the given slice, 1408 or if the slice is empty, or if the function is nil. Exact inverse of `Some`. 1409 */ 1410 func None[A any](src []A, fun func(A) bool) bool { return !Some(src, fun) } 1411 1412 // Same as global `None`. 1413 func (self Slice[A]) None(fun func(A) bool) bool { return None(self, fun) } 1414 1415 /* 1416 Utility for comparing slices pairwise. Returns true if the slices have the same 1417 length and the function returns true for at least one pair. 1418 */ 1419 func SomePair[A any](one, two []A, fun func(A, A) bool) bool { 1420 if len(one) != len(two) || fun == nil { 1421 return false 1422 } 1423 for ind := range one { 1424 if fun(one[ind], two[ind]) { 1425 return true 1426 } 1427 } 1428 return false 1429 } 1430 1431 /* 1432 True if the given function returns true for every element of the given slice. 1433 False if the function is nil. True if the slice is empty. 1434 */ 1435 func Every[A any](src []A, fun func(A) bool) bool { 1436 if fun == nil { 1437 return false 1438 } 1439 for _, val := range src { 1440 if !fun(val) { 1441 return false 1442 } 1443 } 1444 return true 1445 } 1446 1447 // Same as global `Every`. 1448 func (self Slice[A]) Every(fun func(A) bool) bool { return Every(self, fun) } 1449 1450 /* 1451 Utility for comparing slices pairwise. Returns true if the slices have the same 1452 length and the function returns true for every pair. 1453 */ 1454 func EveryPair[A any](one, two []A, fun func(A, A) bool) bool { 1455 if len(one) != len(two) || fun == nil { 1456 return false 1457 } 1458 for ind := range one { 1459 if !fun(one[ind], two[ind]) { 1460 return false 1461 } 1462 } 1463 return true 1464 } 1465 1466 // Concatenates the inputs. If every input is nil, output is nil. 1467 func Concat[Slice ~[]Elem, Elem any](val ...Slice) Slice { 1468 if Every(val, IsZero[Slice]) { 1469 return nil 1470 } 1471 1472 buf := make(Slice, 0, Lens(val...)) 1473 for _, val := range val { 1474 buf = append(buf, val...) 1475 } 1476 return buf 1477 } 1478 1479 /* 1480 Tool for comparing slice elements pairwise. Iterates left-to-right, invoking the 1481 given function for each element pair. If the function is nil, returns false. If 1482 there are 0 or 1 elements, returns true. If every comparison returned true, 1483 returns true. Otherwise returns false. 1484 */ 1485 func IsSorted[A any](src []A, fun func(A, A) bool) bool { 1486 if fun == nil { 1487 return false 1488 } 1489 1490 switch len(src) { 1491 case 0, 1: 1492 return true 1493 1494 case 2: 1495 return fun(src[0], src[1]) 1496 1497 default: 1498 prev := src[0] 1499 for _, next := range src[1:] { 1500 if fun(prev, next) { 1501 prev = next 1502 continue 1503 } 1504 return false 1505 } 1506 return true 1507 } 1508 } 1509 1510 // Sorts a slice of comparable primitives. For non-primitives, see `Sort`. 1511 func SortPrim[A LesserPrim](val []A) { SortablePrim[A](val).Sort() } 1512 1513 /* 1514 Sorts a slice of comparable primitives, mutating and returning that slice. 1515 For non-primitives, see `Sort`. 1516 */ 1517 func SortedPrim[Slice ~[]Elem, Elem LesserPrim](val Slice) Slice { 1518 return Slice(SortablePrim[Elem](val).Sorted()) 1519 } 1520 1521 // Slice of primitives that implements `sort.Interface`. 1522 type SortablePrim[A LesserPrim] []A 1523 1524 // Implement `sort.Interface`. 1525 func (self SortablePrim[_]) Len() int { return len(self) } 1526 1527 // Implement `sort.Interface`. 1528 func (self SortablePrim[_]) Less(one, two int) bool { return self[one] < self[two] } 1529 1530 // Implement `sort.Interface`. 1531 func (self SortablePrim[_]) Swap(one, two int) { Swap(self, one, two) } 1532 1533 // Sorts the receiver, mutating it. 1534 func (self SortablePrim[_]) Sort() { sort.Stable(NoEscUnsafe(sort.Interface(self))) } 1535 1536 // Sorts the receiver, mutating and returning it. 1537 func (self SortablePrim[A]) Sorted() SortablePrim[A] { 1538 self.Sort() 1539 return self 1540 } 1541 1542 // Sorts a slice of comparable non-primitives. For primitives, see `SortPrim`. 1543 func Sort[A Lesser[A]](val []A) { Sortable[A](val).Sort() } 1544 1545 /* 1546 Sorts a slice of comparable values, mutating and returning that slice. 1547 For primitives, see `SortedPrim`. 1548 */ 1549 func Sorted[Slice ~[]Elem, Elem Lesser[Elem]](val Slice) Slice { 1550 return Slice(Sortable[Elem](val).Sorted()) 1551 } 1552 1553 // Slice of non-primitives that implements `sort.Interface`. 1554 type Sortable[A Lesser[A]] []A 1555 1556 // Implement `sort.Interface`. 1557 func (self Sortable[_]) Len() int { return len(self) } 1558 1559 // Implement `sort.Interface`. 1560 func (self Sortable[_]) Less(one, two int) bool { return self[one].Less(self[two]) } 1561 1562 // Implement `sort.Interface`. 1563 func (self Sortable[_]) Swap(one, two int) { Swap(self, one, two) } 1564 1565 // Sorts the receiver, mutating it. 1566 func (self Sortable[_]) Sort() { sort.Stable(NoEscUnsafe(sort.Interface(self))) } 1567 1568 // Sorts the receiver, mutating and returning it. 1569 func (self Sortable[A]) Sorted() Sortable[A] { 1570 self.Sort() 1571 return self 1572 } 1573 1574 // Reverses the given slice in-place, mutating it. 1575 func Reverse[A any](val []A) { 1576 ind0 := 0 1577 ind1 := len(val) - 1 1578 1579 for ind0 < ind1 { 1580 val[ind0], val[ind1] = val[ind1], val[ind0] 1581 ind0++ 1582 ind1-- 1583 } 1584 } 1585 1586 // Same as global `Reverse`. 1587 func (self Slice[_]) Reverse() { Reverse(self) } 1588 1589 // Reverses the given slice in-place, mutating it and returning that slice. 1590 func Reversed[Slice ~[]Elem, Elem any](val Slice) Slice { 1591 Reverse(val) 1592 return val 1593 } 1594 1595 // Same as global `Reversed`. 1596 func (self Slice[A]) Reversed() Slice[A] { return Reversed(self) } 1597 1598 // Swaps the two elements at the given indexes in the given slice. 1599 func Swap[Slice ~[]Elem, Elem any](tar Slice, one, two int) { 1600 tar[one], tar[two] = tar[two], tar[one] 1601 } 1602 1603 // Same as global `Swap`. 1604 func (self Slice[A]) Swap(one, two int) { Swap(self, one, two) }