github.com/andeya/ameda@v1.5.3/uints.go (about) 1 package ameda 2 3 // OneUint try to return the first element, otherwise return zero value. 4 func OneUint(u []uint) uint { 5 if len(u) > 0 { 6 return u[0] 7 } 8 return 0 9 } 10 11 // UintsCopy creates a copy of the uint slice. 12 func UintsCopy(u []uint) []uint { 13 b := make([]uint, len(u)) 14 copy(b, u) 15 return b 16 } 17 18 // UintsToInterfaces converts uint slice to interface slice. 19 func UintsToInterfaces(u []uint) []interface{} { 20 r := make([]interface{}, len(u)) 21 for k, v := range u { 22 r[k] = UintToInterface(v) 23 } 24 return r 25 } 26 27 // UintsToStrings converts uint slice to string slice. 28 func UintsToStrings(u []uint) []string { 29 r := make([]string, len(u)) 30 for k, v := range u { 31 r[k] = UintToString(v) 32 } 33 return r 34 } 35 36 // UintsToBools converts uint slice to bool slice. 37 // NOTE: 38 // 39 // 0 is false, everything else is true 40 func UintsToBools(u []uint) []bool { 41 r := make([]bool, len(u)) 42 for k, v := range u { 43 r[k] = UintToBool(v) 44 } 45 return r 46 } 47 48 // UintsToFloat32s converts uint slice to float32 slice. 49 func UintsToFloat32s(u []uint) []float32 { 50 r := make([]float32, len(u)) 51 for k, v := range u { 52 r[k] = UintToFloat32(v) 53 } 54 return r 55 } 56 57 // UintsToFloat64s converts uint slice to float64 slice. 58 func UintsToFloat64s(u []uint) []float64 { 59 r := make([]float64, len(u)) 60 for k, v := range u { 61 r[k] = UintToFloat64(v) 62 } 63 return r 64 } 65 66 // UintsToInts converts uint slice to int slice. 67 func UintsToInts(u []uint) ([]int, error) { 68 var err error 69 r := make([]int, len(u)) 70 for k, v := range u { 71 r[k], err = UintToInt(v) 72 if err != nil { 73 return r, err 74 } 75 } 76 return r, nil 77 } 78 79 // UintsToInt8s converts uint slice to int8 slice. 80 func UintsToInt8s(u []uint) ([]int8, error) { 81 var err error 82 r := make([]int8, len(u)) 83 for k, v := range u { 84 r[k], err = UintToInt8(v) 85 if err != nil { 86 return r, err 87 } 88 } 89 return r, nil 90 } 91 92 // UintsToInt16s converts uint slice to int16 slice. 93 func UintsToInt16s(u []uint) ([]int16, error) { 94 var err error 95 r := make([]int16, len(u)) 96 for k, v := range u { 97 r[k], err = UintToInt16(v) 98 if err != nil { 99 return r, err 100 } 101 } 102 return r, nil 103 } 104 105 // UintsToInt32s converts uint slice to int32 slice. 106 func UintsToInt32s(u []uint) ([]int32, error) { 107 var err error 108 r := make([]int32, len(u)) 109 for k, v := range u { 110 r[k], err = UintToInt32(v) 111 if err != nil { 112 return r, err 113 } 114 } 115 return r, nil 116 } 117 118 // UintsToInt64s converts uint slice to int64 slice. 119 func UintsToInt64s(u []uint) ([]int64, error) { 120 var err error 121 r := make([]int64, len(u)) 122 for k, v := range u { 123 r[k], err = UintToInt64(v) 124 if err != nil { 125 return r, err 126 } 127 } 128 return r, nil 129 } 130 131 // UintsToUint8s converts uint slice to uint8 slice. 132 func UintsToUint8s(u []uint) ([]uint8, error) { 133 var err error 134 r := make([]uint8, len(u)) 135 for k, v := range u { 136 r[k], err = UintToUint8(v) 137 if err != nil { 138 return r, err 139 } 140 } 141 return r, nil 142 } 143 144 // UintsToUint16s converts uint slice to uint16 slice. 145 func UintsToUint16s(u []uint) ([]uint16, error) { 146 var err error 147 r := make([]uint16, len(u)) 148 for k, v := range u { 149 r[k], err = UintToUint16(v) 150 if err != nil { 151 return r, err 152 } 153 } 154 return r, nil 155 } 156 157 // UintsToUint32s converts uint slice to uint32 slice. 158 func UintsToUint32s(u []uint) ([]uint32, error) { 159 var err error 160 r := make([]uint32, len(u)) 161 for k, v := range u { 162 r[k], err = UintToUint32(v) 163 if err != nil { 164 return r, err 165 } 166 } 167 return r, nil 168 } 169 170 // UintsToUint64s converts uint slice to uint64 slice. 171 func UintsToUint64s(u []uint) []uint64 { 172 r := make([]uint64, len(u)) 173 for k, v := range u { 174 r[k] = UintToUint64(v) 175 } 176 return r 177 } 178 179 // UintsCopyWithin copies part of an slice to another location in the current slice. 180 // @target 181 // 182 // Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. 183 // 184 // @start 185 // 186 // Zero-based index at which to start copying elements from. If negative, start will be counted from the end. 187 // 188 // @end 189 // 190 // Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. 191 // If negative, end will be counted from the end. 192 // If end is omitted, CopyWithin will copy until the last index (default to len(s)). 193 func UintsCopyWithin(u []uint, target, start int, end ...int) { 194 target = fixIndex(len(u), target, true) 195 if target == len(u) { 196 return 197 } 198 sub := UintsSlice(u, start, end...) 199 for k, v := range sub { 200 u[target+k] = v 201 } 202 } 203 204 // UintsEvery tests whether all elements in the slice pass the test implemented by the provided function. 205 // NOTE: 206 // 207 // Calling this method on an empty slice will return true for any condition! 208 func UintsEvery(u []uint, fn func(u []uint, k int, v uint) bool) bool { 209 for k, v := range u { 210 if !fn(u, k, v) { 211 return false 212 } 213 } 214 return true 215 } 216 217 // UintsFill changes all elements in the current slice to a value, from a start index to an end index. 218 // @value 219 // 220 // Zero-based index at which to copy the sequence to. If negative, target will be counted from the end. 221 // 222 // @start 223 // 224 // Zero-based index at which to start copying elements from. If negative, start will be counted from the end. 225 // 226 // @end 227 // 228 // Zero-based index at which to end copying elements from. CopyWithin copies up to but not including end. 229 // If negative, end will be counted from the end. 230 // If end is omitted, CopyWithin will copy until the last index (default to len(s)). 231 func UintsFill(u []uint, value uint, start int, end ...int) { 232 fixedStart, fixedEnd, ok := fixRange(len(u), start, end...) 233 if !ok { 234 return 235 } 236 for k := fixedStart; k < fixedEnd; k++ { 237 u[k] = value 238 } 239 } 240 241 // UintsFilter creates a new slice with all elements that pass the test implemented by the provided function. 242 func UintsFilter(u []uint, fn func(u []uint, k int, v uint) bool) []uint { 243 ret := make([]uint, 0) 244 for k, v := range u { 245 if fn(u, k, v) { 246 ret = append(ret, v) 247 } 248 } 249 return ret 250 } 251 252 // UintsFind returns the key-value of the first element in the provided slice that satisfies the provided testing function. 253 // NOTE: 254 // 255 // If not found, k = -1 256 func UintsFind(u []uint, fn func(u []uint, k int, v uint) bool) (k int, v uint) { 257 for k, v := range u { 258 if fn(u, k, v) { 259 return k, v 260 } 261 } 262 return -1, 0 263 } 264 265 // UintsIncludes determines whether an slice includes a certain value among its entries. 266 // @fromIndex 267 // 268 // The index to start the search at. Defaults to 0. 269 func UintsIncludes(u []uint, valueToFind uint, fromIndex ...int) bool { 270 return UintsIndexOf(u, valueToFind, fromIndex...) > -1 271 } 272 273 // UintsIndexOf returns the first index at which a given element can be found in the slice, or -1 if it is not present. 274 // @fromIndex 275 // 276 // The index to start the search at. Defaults to 0. 277 func UintsIndexOf(u []uint, searchElement uint, fromIndex ...int) int { 278 idx := getFromIndex(len(u), fromIndex...) 279 for k, v := range u[idx:] { 280 if searchElement == v { 281 return k + idx 282 } 283 } 284 return -1 285 } 286 287 // UintsLastIndexOf returns the last index at which a given element can be found in the slice, or -1 if it is not present. 288 // @fromIndex 289 // 290 // The index to start the search at. Defaults to 0. 291 func UintsLastIndexOf(u []uint, searchElement uint, fromIndex ...int) int { 292 idx := getFromIndex(len(u), fromIndex...) 293 for k := len(u) - 1; k >= idx; k-- { 294 if searchElement == u[k] { 295 return k 296 } 297 } 298 return -1 299 } 300 301 // UintsMap creates a new slice populated with the results of calling a provided function 302 // on every element in the calling slice. 303 func UintsMap(u []uint, fn func(u []uint, k int, v uint) uint) []uint { 304 ret := make([]uint, len(u)) 305 for k, v := range u { 306 ret[k] = fn(u, k, v) 307 } 308 return ret 309 } 310 311 // UintsPop removes the last element from an slice and returns that element. 312 // This method changes the length of the slice. 313 func UintsPop(u *[]uint) (uint, bool) { 314 a := *u 315 if len(a) == 0 { 316 return 0, false 317 } 318 lastIndex := len(a) - 1 319 last := a[lastIndex] 320 a = a[:lastIndex] 321 *u = a[:len(a):len(a)] 322 return last, true 323 } 324 325 // UintsPush adds one or more elements to the end of an slice and returns the new length of the slice. 326 func UintsPush(u *[]uint, element ...uint) int { 327 *u = append(*u, element...) 328 return len(*u) 329 } 330 331 // UintsPushDistinct adds one or more new elements that do not exist in the current slice at the end. 332 func UintsPushDistinct(u []uint, element ...uint) []uint { 333 L: 334 for _, v := range element { 335 for _, vv := range u { 336 if vv == v { 337 continue L 338 } 339 } 340 u = append(u, v) 341 } 342 return u 343 } 344 345 // UintsReduce executes a reducer function (that you provide) on each element of the slice, 346 // resulting in a single output value. 347 // @accumulator 348 // 349 // The accumulator accumulates callback's return values. 350 // It is the accumulated value previously returned in the last invocation of the callback—or initialValue, 351 // if it was supplied (see below). 352 // 353 // @initialValue 354 // 355 // A value to use as the first argument to the first call of the callback. 356 // If no initialValue is supplied, the first element in the slice will be used and skipped. 357 func UintsReduce(u []uint, 358 fn func(u []uint, k int, v, accumulator uint) uint, initialValue ...uint, 359 ) uint { 360 if len(u) == 0 { 361 return 0 362 } 363 start := 0 364 acc := u[start] 365 if len(initialValue) > 0 { 366 acc = initialValue[0] 367 } else { 368 start += 1 369 } 370 for k := start; k < len(u); k++ { 371 acc = fn(u, k, u[k], acc) 372 } 373 return acc 374 } 375 376 // UintsReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) 377 // to reduce it to a single value. 378 // @accumulator 379 // 380 // The accumulator accumulates callback's return values. 381 // It is the accumulated value previously returned in the last invocation of the callback—or initialValue, 382 // if it was supplied (see below). 383 // 384 // @initialValue 385 // 386 // A value to use as the first argument to the first call of the callback. 387 // If no initialValue is supplied, the first element in the slice will be used and skipped. 388 func UintsReduceRight(u []uint, 389 fn func(u []uint, k int, v, accumulator uint) uint, initialValue ...uint, 390 ) uint { 391 if len(u) == 0 { 392 return 0 393 } 394 end := len(u) - 1 395 acc := u[end] 396 if len(initialValue) > 0 { 397 acc = initialValue[0] 398 } else { 399 end -= 1 400 } 401 for k := end; k >= 0; k-- { 402 acc = fn(u, k, u[k], acc) 403 } 404 return acc 405 } 406 407 // UintsReverse reverses an slice in place. 408 func UintsReverse(u []uint) { 409 first := 0 410 last := len(u) - 1 411 for first < last { 412 u[first], u[last] = u[last], u[first] 413 first++ 414 last-- 415 } 416 } 417 418 // UintsShift removes the first element from an slice and returns that removed element. 419 // This method changes the length of the slice. 420 func UintsShift(u *[]uint) (uint, bool) { 421 a := *u 422 if len(a) == 0 { 423 return 0, false 424 } 425 first := a[0] 426 a = a[1:] 427 *u = a[:len(a):len(a)] 428 return first, true 429 } 430 431 // UintsSlice returns a copy of a portion of an slice into a new slice object selected 432 // from begin to end (end not included) where begin and end represent the index of items in that slice. 433 // The original slice will not be modified. 434 func UintsSlice(u []uint, begin int, end ...int) []uint { 435 fixedStart, fixedEnd, ok := fixRange(len(u), begin, end...) 436 if !ok { 437 return []uint{} 438 } 439 return UintsCopy(u[fixedStart:fixedEnd]) 440 } 441 442 // UintsSome tests whether at least one element in the slice passes the test implemented by the provided function. 443 // NOTE: 444 // 445 // Calling this method on an empty slice returns false for any condition! 446 func UintsSome(u []uint, fn func(u []uint, k int, v uint) bool) bool { 447 for k, v := range u { 448 if fn(u, k, v) { 449 return true 450 } 451 } 452 return false 453 } 454 455 // UintsSplice changes the contents of an slice by removing or replacing 456 // existing elements and/or adding new elements in place. 457 func UintsSplice(u *[]uint, start, deleteCount int, items ...uint) { 458 a := *u 459 if deleteCount < 0 { 460 deleteCount = 0 461 } 462 start, end, _ := fixRange(len(a), start, start+1+deleteCount) 463 deleteCount = end - start - 1 464 for k := 0; k < len(items); k++ { 465 if deleteCount > 0 { 466 // replace 467 a[start] = items[k] 468 deleteCount-- 469 start++ 470 } else { 471 // insert 472 lastSlice := UintsCopy(a[start:]) 473 items = items[k:] 474 a = append(a[:start], items...) 475 a = append(a[:start+len(items)], lastSlice...) 476 *u = a[:len(a):len(a)] 477 return 478 } 479 } 480 if deleteCount > 0 { 481 a = append(a[:start], a[start+1+deleteCount:]...) 482 } 483 *u = a[:len(a):len(a)] 484 } 485 486 // UintsUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. 487 func UintsUnshift(u *[]uint, element ...uint) int { 488 *u = append(element, *u...) 489 return len(*u) 490 } 491 492 // UintsUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning 493 // and returns the new length of the slice. 494 func UintsUnshiftDistinct(u *[]uint, element ...uint) int { 495 a := *u 496 if len(element) == 0 { 497 return len(a) 498 } 499 m := make(map[uint]bool, len(element)) 500 r := make([]uint, 0, len(a)+len(element)) 501 L: 502 for _, v := range element { 503 if m[v] { 504 continue 505 } 506 m[v] = true 507 for _, vv := range a { 508 if vv == v { 509 continue L 510 } 511 } 512 r = append(r, v) 513 } 514 r = append(r, a...) 515 *u = r[:len(r):len(r)] 516 return len(r) 517 } 518 519 // UintsRemoveFirst removes the first matched elements from the slice, 520 // and returns the new length of the slice. 521 func UintsRemoveFirst(p *[]uint, elements ...uint) int { 522 a := *p 523 m := make(map[interface{}]struct{}, len(elements)) 524 for _, element := range elements { 525 if _, ok := m[element]; ok { 526 continue 527 } 528 m[element] = struct{}{} 529 for k, v := range a { 530 if v == element { 531 a = append(a[:k], a[k+1:]...) 532 break 533 } 534 } 535 } 536 n := len(a) 537 *p = a[:n:n] 538 return n 539 } 540 541 // UintsRemoveEvery removes all the elements from the slice, 542 // and returns the new length of the slice. 543 func UintsRemoveEvery(p *[]uint, elements ...uint) int { 544 a := *p 545 m := make(map[interface{}]struct{}, len(elements)) 546 for _, element := range elements { 547 if _, ok := m[element]; ok { 548 continue 549 } 550 m[element] = struct{}{} 551 for i := 0; i < len(a); i++ { 552 if a[i] == element { 553 a = append(a[:i], a[i+1:]...) 554 i-- 555 } 556 } 557 } 558 n := len(a) 559 *p = a[:n:n] 560 return n 561 } 562 563 // UintsConcat is used to merge two or more slices. 564 // This method does not change the existing slices, but instead returns a new slice. 565 func UintsConcat(u ...[]uint) []uint { 566 var totalLen int 567 for _, v := range u { 568 totalLen += len(v) 569 } 570 ret := make([]uint, totalLen) 571 dst := ret 572 for _, v := range u { 573 n := copy(dst, v) 574 dst = dst[n:] 575 } 576 return ret 577 } 578 579 // UintsIntersect calculates intersection of two or more slices, 580 // and returns the count of each element. 581 func UintsIntersect(u ...[]uint) (intersectCount map[uint]int) { 582 if len(u) == 0 { 583 return nil 584 } 585 for _, v := range u { 586 if len(v) == 0 { 587 return nil 588 } 589 } 590 counts := make([]map[uint]int, len(u)) 591 for k, v := range u { 592 counts[k] = uintsDistinct(v, nil) 593 } 594 intersectCount = counts[0] 595 L: 596 for k, v := range intersectCount { 597 for _, c := range counts[1:] { 598 v2 := c[k] 599 if v2 == 0 { 600 delete(intersectCount, k) 601 continue L 602 } 603 if v > v2 { 604 v = v2 605 } 606 } 607 intersectCount[k] = v 608 } 609 return intersectCount 610 } 611 612 // UintsDistinct calculates the count of each different element, 613 // and only saves these different elements in place if changeSlice is true. 614 func UintsDistinct(i *[]uint, changeSlice bool) (distinctCount map[uint]int) { 615 if !changeSlice { 616 return uintsDistinct(*i, nil) 617 } 618 a := (*i)[:0] 619 distinctCount = uintsDistinct(*i, &a) 620 n := len(distinctCount) 621 *i = a[:n:n] 622 return distinctCount 623 } 624 625 func uintsDistinct(src []uint, dst *[]uint) map[uint]int { 626 m := make(map[uint]int, len(src)) 627 if dst == nil { 628 for _, v := range src { 629 n := m[v] 630 m[v] = n + 1 631 } 632 } else { 633 a := *dst 634 for _, v := range src { 635 n := m[v] 636 m[v] = n + 1 637 if n == 0 { 638 a = append(a, v) 639 } 640 } 641 *dst = a 642 } 643 return m 644 } 645 646 // UintSetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... 647 // This method does not change the existing slices, but instead returns a new slice. 648 func UintSetUnion(set1, set2 []uint, others ...[]uint) []uint { 649 m := make(map[uint]struct{}, len(set1)+len(set2)) 650 r := make([]uint, 0, len(m)) 651 for _, set := range append([][]uint{set1, set2}, others...) { 652 for _, v := range set { 653 _, ok := m[v] 654 if ok { 655 continue 656 } 657 r = append(r, v) 658 m[v] = struct{}{} 659 } 660 } 661 return r 662 } 663 664 // UintSetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... 665 // This method does not change the existing slices, but instead returns a new slice. 666 func UintSetIntersect(set1, set2 []uint, others ...[]uint) []uint { 667 sets := append([][]uint{set2}, others...) 668 setsCount := make([]map[uint]int, len(sets)) 669 for k, v := range sets { 670 setsCount[k] = uintsDistinct(v, nil) 671 } 672 m := make(map[uint]struct{}, len(set1)) 673 r := make([]uint, 0, len(m)) 674 L: 675 for _, v := range set1 { 676 if _, ok := m[v]; ok { 677 continue 678 } 679 m[v] = struct{}{} 680 for _, m2 := range setsCount { 681 if m2[v] == 0 { 682 continue L 683 } 684 } 685 r = append(r, v) 686 } 687 return r 688 } 689 690 // UintSetDifference calculates between multiple collections: set1 - set2 - others... 691 // This method does not change the existing slices, but instead returns a new slice. 692 func UintSetDifference(set1, set2 []uint, others ...[]uint) []uint { 693 m := make(map[uint]struct{}, len(set1)) 694 r := make([]uint, 0, len(set1)) 695 sets := append([][]uint{set2}, others...) 696 for _, v := range sets { 697 inter := UintSetIntersect(set1, v) 698 for _, v := range inter { 699 m[v] = struct{}{} 700 } 701 } 702 for _, v := range set1 { 703 if _, ok := m[v]; !ok { 704 r = append(r, v) 705 m[v] = struct{}{} 706 } 707 } 708 return r 709 }