github.com/andeya/ameda@v1.5.3/ints.go (about) 1 package ameda 2 3 // OneInt try to return the first element, otherwise return zero value. 4 func OneInt(i []int) int { 5 if len(i) > 0 { 6 return i[0] 7 } 8 return 0 9 } 10 11 // IntsCopy creates a copy of the int slice. 12 func IntsCopy(i []int) []int { 13 b := make([]int, len(i)) 14 copy(b, i) 15 return b 16 } 17 18 // IntsToInterfaces converts int slice to interface slice. 19 func IntsToInterfaces(i []int) []interface{} { 20 r := make([]interface{}, len(i)) 21 for k, v := range i { 22 r[k] = IntToInterface(v) 23 } 24 return r 25 } 26 27 // IntsToStrings converts int slice to string slice. 28 func IntsToStrings(i []int) []string { 29 r := make([]string, len(i)) 30 for k, v := range i { 31 r[k] = IntToString(v) 32 } 33 return r 34 } 35 36 // IntsToBools converts int slice to bool slice. 37 // NOTE: 38 // 39 // 0 is false, everything else is true 40 func IntsToBools(i []int) []bool { 41 r := make([]bool, len(i)) 42 for k, v := range i { 43 r[k] = IntToBool(v) 44 } 45 return r 46 } 47 48 // IntsToFloat32s converts int slice to float32 slice. 49 func IntsToFloat32s(i []int) []float32 { 50 r := make([]float32, len(i)) 51 for k, v := range i { 52 r[k] = IntToFloat32(v) 53 } 54 return r 55 } 56 57 // IntsToFloat64s converts int slice to float64 slice. 58 func IntsToFloat64s(i []int) []float64 { 59 r := make([]float64, len(i)) 60 for k, v := range i { 61 r[k] = IntToFloat64(v) 62 } 63 return r 64 } 65 66 // IntsToInt8s converts int slice to int8 slice. 67 func IntsToInt8s(i []int) ([]int8, error) { 68 var err error 69 r := make([]int8, len(i)) 70 for k, v := range i { 71 r[k], err = IntToInt8(v) 72 if err != nil { 73 return r, err 74 } 75 } 76 return r, nil 77 } 78 79 // IntsToInt16s converts int slice to int16 slice. 80 func IntsToInt16s(i []int) ([]int16, error) { 81 var err error 82 r := make([]int16, len(i)) 83 for k, v := range i { 84 r[k], err = IntToInt16(v) 85 if err != nil { 86 return r, err 87 } 88 } 89 return r, nil 90 } 91 92 // IntsToInt32s converts int slice to int32 slice. 93 func IntsToInt32s(i []int) ([]int32, error) { 94 var err error 95 r := make([]int32, len(i)) 96 for k, v := range i { 97 r[k], err = IntToInt32(v) 98 if err != nil { 99 return r, err 100 } 101 } 102 return r, nil 103 } 104 105 // IntsToInt64s converts int slice to int64 slice. 106 func IntsToInt64s(i []int) []int64 { 107 r := make([]int64, len(i)) 108 for k, v := range i { 109 r[k] = IntToInt64(v) 110 } 111 return r 112 } 113 114 // IntsToUints converts int slice to uint slice. 115 func IntsToUints(i []int) ([]uint, error) { 116 var err error 117 r := make([]uint, len(i)) 118 for k, v := range i { 119 r[k], err = IntToUint(v) 120 if err != nil { 121 return r, err 122 } 123 } 124 return r, nil 125 } 126 127 // IntsToUint8s converts int slice to uint8 slice. 128 func IntsToUint8s(i []int) ([]uint8, error) { 129 var err error 130 r := make([]uint8, len(i)) 131 for k, v := range i { 132 r[k], err = IntToUint8(v) 133 if err != nil { 134 return r, err 135 } 136 } 137 return r, nil 138 } 139 140 // IntsToUint16s converts int slice to uint16 slice. 141 func IntsToUint16s(i []int) ([]uint16, error) { 142 var err error 143 r := make([]uint16, len(i)) 144 for k, v := range i { 145 r[k], err = IntToUint16(v) 146 if err != nil { 147 return r, err 148 } 149 } 150 return r, nil 151 } 152 153 // IntsToUint32s converts int slice to uint32 slice. 154 func IntsToUint32s(i []int) ([]uint32, error) { 155 var err error 156 r := make([]uint32, len(i)) 157 for k, v := range i { 158 r[k], err = IntToUint32(v) 159 if err != nil { 160 return r, err 161 } 162 } 163 return r, nil 164 } 165 166 // IntsToUint64s converts int slice to uint64 slice. 167 func IntsToUint64s(i []int) ([]uint64, error) { 168 var err error 169 r := make([]uint64, len(i)) 170 for k, v := range i { 171 r[k], err = IntToUint64(v) 172 if err != nil { 173 return r, err 174 } 175 } 176 return r, nil 177 } 178 179 // IntsCopyWithin 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 IntsCopyWithin(i []int, target, start int, end ...int) { 194 target = fixIndex(len(i), target, true) 195 if target == len(i) { 196 return 197 } 198 sub := IntsSlice(i, start, end...) 199 for k, v := range sub { 200 i[target+k] = v 201 } 202 } 203 204 // IntsEvery 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 IntsEvery(i []int, fn func(i []int, k int, v int) bool) bool { 209 for k, v := range i { 210 if !fn(i, k, v) { 211 return false 212 } 213 } 214 return true 215 } 216 217 // IntsFill 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 IntsFill(i []int, value int, start int, end ...int) { 232 fixedStart, fixedEnd, ok := fixRange(len(i), start, end...) 233 if !ok { 234 return 235 } 236 for k := fixedStart; k < fixedEnd; k++ { 237 i[k] = value 238 } 239 } 240 241 // IntsFilter creates a new slice with all elements that pass the test implemented by the provided function. 242 func IntsFilter(i []int, fn func(i []int, k int, v int) bool) []int { 243 ret := make([]int, 0) 244 for k, v := range i { 245 if fn(i, k, v) { 246 ret = append(ret, v) 247 } 248 } 249 return ret 250 } 251 252 // IntsFind 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 IntsFind(i []int, fn func(i []int, k int, v int) bool) (k int, v int) { 257 for k, v := range i { 258 if fn(i, k, v) { 259 return k, v 260 } 261 } 262 return -1, 0 263 } 264 265 // IntsIncludes 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 IntsIncludes(i []int, valueToFind int, fromIndex ...int) bool { 270 return IntsIndexOf(i, valueToFind, fromIndex...) > -1 271 } 272 273 // IntsIndexOf 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 IntsIndexOf(i []int, searchElement int, fromIndex ...int) int { 278 idx := getFromIndex(len(i), fromIndex...) 279 for k, v := range i[idx:] { 280 if searchElement == v { 281 return k + idx 282 } 283 } 284 return -1 285 } 286 287 // IntsLastIndexOf 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 IntsLastIndexOf(i []int, searchElement int, fromIndex ...int) int { 292 idx := getFromIndex(len(i), fromIndex...) 293 for k := len(i) - 1; k >= idx; k-- { 294 if searchElement == i[k] { 295 return k 296 } 297 } 298 return -1 299 } 300 301 // IntsMap creates a new slice populated with the results of calling a provided function 302 // on every element in the calling slice. 303 func IntsMap(i []int, fn func(i []int, k int, v int) int) []int { 304 ret := make([]int, len(i)) 305 for k, v := range i { 306 ret[k] = fn(i, k, v) 307 } 308 return ret 309 } 310 311 // IntsPop removes the last element from an slice and returns that element. 312 // This method changes the length of the slice. 313 func IntsPop(i *[]int) (int, bool) { 314 a := *i 315 if len(a) == 0 { 316 return 0, false 317 } 318 lastIndex := len(a) - 1 319 last := a[lastIndex] 320 a = a[:lastIndex] 321 *i = a[:len(a):len(a)] 322 return last, true 323 } 324 325 // IntsPush adds one or more elements to the end of an slice and returns the new length of the slice. 326 func IntsPush(i *[]int, element ...int) int { 327 *i = append(*i, element...) 328 return len(*i) 329 } 330 331 // IntsPushDistinct adds one or more new elements that do not exist in the current slice at the end. 332 func IntsPushDistinct(i []int, element ...int) []int { 333 L: 334 for _, v := range element { 335 for _, vv := range i { 336 if vv == v { 337 continue L 338 } 339 } 340 i = append(i, v) 341 } 342 return i 343 } 344 345 // IntsReduce 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 IntsReduce(i []int, fn func(i []int, k int, v, accumulator int) int, initialValue ...int) int { 358 if len(i) == 0 { 359 return 0 360 } 361 start := 0 362 acc := i[start] 363 if len(initialValue) > 0 { 364 acc = initialValue[0] 365 } else { 366 start += 1 367 } 368 for k := start; k < len(i); k++ { 369 acc = fn(i, k, i[k], acc) 370 } 371 return acc 372 } 373 374 // IntsReduceRight applies a function against an accumulator and each value of the slice (from right-to-left) 375 // to reduce it to a single value. 376 // @accumulator 377 // 378 // The accumulator accumulates callback's return values. 379 // It is the accumulated value previously returned in the last invocation of the callback—or initialValue, 380 // if it was supplied (see below). 381 // 382 // @initialValue 383 // 384 // A value to use as the first argument to the first call of the callback. 385 // If no initialValue is supplied, the first element in the slice will be used and skipped. 386 func IntsReduceRight(i []int, fn func(i []int, k int, v, accumulator int) int, initialValue ...int) int { 387 if len(i) == 0 { 388 return 0 389 } 390 end := len(i) - 1 391 acc := i[end] 392 if len(initialValue) > 0 { 393 acc = initialValue[0] 394 } else { 395 end -= 1 396 } 397 for k := end; k >= 0; k-- { 398 acc = fn(i, k, i[k], acc) 399 } 400 return acc 401 } 402 403 // IntsReverse reverses an slice in place. 404 func IntsReverse(i []int) { 405 first := 0 406 last := len(i) - 1 407 for first < last { 408 i[first], i[last] = i[last], i[first] 409 first++ 410 last-- 411 } 412 } 413 414 // IntsShift removes the first element from an slice and returns that removed element. 415 // This method changes the length of the slice. 416 func IntsShift(i *[]int) (int, bool) { 417 a := *i 418 if len(a) == 0 { 419 return 0, false 420 } 421 first := a[0] 422 a = a[1:] 423 *i = a[:len(a):len(a)] 424 return first, true 425 } 426 427 // IntsSlice returns a copy of a portion of an slice into a new slice object selected 428 // from begin to end (end not included) where begin and end represent the index of items in that slice. 429 // The original slice will not be modified. 430 func IntsSlice(i []int, begin int, end ...int) []int { 431 fixedStart, fixedEnd, ok := fixRange(len(i), begin, end...) 432 if !ok { 433 return []int{} 434 } 435 return IntsCopy(i[fixedStart:fixedEnd]) 436 } 437 438 // IntsSome tests whether at least one element in the slice passes the test implemented by the provided function. 439 // NOTE: 440 // 441 // Calling this method on an empty slice returns false for any condition! 442 func IntsSome(i []int, fn func(i []int, k int, v int) bool) bool { 443 for k, v := range i { 444 if fn(i, k, v) { 445 return true 446 } 447 } 448 return false 449 } 450 451 // IntsSplice changes the contents of an slice by removing or replacing 452 // existing elements and/or adding new elements in place. 453 func IntsSplice(i *[]int, start, deleteCount int, items ...int) { 454 a := *i 455 if deleteCount < 0 { 456 deleteCount = 0 457 } 458 start, end, _ := fixRange(len(a), start, start+1+deleteCount) 459 deleteCount = end - start - 1 460 for k := 0; k < len(items); k++ { 461 if deleteCount > 0 { 462 // replace 463 a[start] = items[k] 464 deleteCount-- 465 start++ 466 } else { 467 // insert 468 lastSlice := IntsCopy(a[start:]) 469 items = items[k:] 470 a = append(a[:start], items...) 471 a = append(a[:start+len(items)], lastSlice...) 472 *i = a[:len(a):len(a)] 473 return 474 } 475 } 476 if deleteCount > 0 { 477 a = append(a[:start], a[start+1+deleteCount:]...) 478 } 479 *i = a[:len(a):len(a)] 480 } 481 482 // IntsUnshift adds one or more elements to the beginning of an slice and returns the new length of the slice. 483 func IntsUnshift(i *[]int, element ...int) int { 484 *i = append(element, *i...) 485 return len(*i) 486 } 487 488 // IntsUnshiftDistinct adds one or more new elements that do not exist in the current slice to the beginning 489 // and returns the new length of the slice. 490 func IntsUnshiftDistinct(i *[]int, element ...int) int { 491 a := *i 492 if len(element) == 0 { 493 return len(a) 494 } 495 m := make(map[int]bool, len(element)) 496 r := make([]int, 0, len(a)+len(element)) 497 L: 498 for _, v := range element { 499 if m[v] { 500 continue 501 } 502 m[v] = true 503 for _, vv := range a { 504 if vv == v { 505 continue L 506 } 507 } 508 r = append(r, v) 509 } 510 r = append(r, a...) 511 *i = r[:len(r):len(r)] 512 return len(r) 513 } 514 515 // IntsRemoveFirst removes the first matched elements from the slice, 516 // and returns the new length of the slice. 517 func IntsRemoveFirst(p *[]int, elements ...int) int { 518 a := *p 519 m := make(map[interface{}]struct{}, len(elements)) 520 for _, element := range elements { 521 if _, ok := m[element]; ok { 522 continue 523 } 524 m[element] = struct{}{} 525 for k, v := range a { 526 if v == element { 527 a = append(a[:k], a[k+1:]...) 528 break 529 } 530 } 531 } 532 n := len(a) 533 *p = a[:n:n] 534 return n 535 } 536 537 // IntsRemoveEvery removes all the elements from the slice, 538 // and returns the new length of the slice. 539 func IntsRemoveEvery(p *[]int, elements ...int) int { 540 a := *p 541 m := make(map[interface{}]struct{}, len(elements)) 542 for _, element := range elements { 543 if _, ok := m[element]; ok { 544 continue 545 } 546 m[element] = struct{}{} 547 for i := 0; i < len(a); i++ { 548 if a[i] == element { 549 a = append(a[:i], a[i+1:]...) 550 i-- 551 } 552 } 553 } 554 n := len(a) 555 *p = a[:n:n] 556 return n 557 } 558 559 // IntsConcat is used to merge two or more slices. 560 // This method does not change the existing slices, but instead returns a new slice. 561 func IntsConcat(i ...[]int) []int { 562 var totalLen int 563 for _, v := range i { 564 totalLen += len(v) 565 } 566 ret := make([]int, totalLen) 567 dst := ret 568 for _, v := range i { 569 n := copy(dst, v) 570 dst = dst[n:] 571 } 572 return ret 573 } 574 575 // IntsIntersect calculates intersection of two or more slices, 576 // and returns the count of each element. 577 func IntsIntersect(i ...[]int) (intersectCount map[int]int) { 578 if len(i) == 0 { 579 return nil 580 } 581 for _, v := range i { 582 if len(v) == 0 { 583 return nil 584 } 585 } 586 counts := make([]map[int]int, len(i)) 587 for k, v := range i { 588 counts[k] = intsDistinct(v, nil) 589 } 590 intersectCount = counts[0] 591 L: 592 for k, v := range intersectCount { 593 for _, c := range counts[1:] { 594 v2 := c[k] 595 if v2 == 0 { 596 delete(intersectCount, k) 597 continue L 598 } 599 if v > v2 { 600 v = v2 601 } 602 } 603 intersectCount[k] = v 604 } 605 return intersectCount 606 } 607 608 // IntsDistinct calculates the count of each different element, 609 // and only saves these different elements in place if changeSlice is true. 610 func IntsDistinct(i *[]int, changeSlice bool) (distinctCount map[int]int) { 611 if !changeSlice { 612 return intsDistinct(*i, nil) 613 } 614 a := (*i)[:0] 615 distinctCount = intsDistinct(*i, &a) 616 n := len(distinctCount) 617 *i = a[:n:n] 618 return distinctCount 619 } 620 621 func intsDistinct(src []int, dst *[]int) map[int]int { 622 m := make(map[int]int, len(src)) 623 if dst == nil { 624 for _, v := range src { 625 n := m[v] 626 m[v] = n + 1 627 } 628 } else { 629 a := *dst 630 for _, v := range src { 631 n := m[v] 632 m[v] = n + 1 633 if n == 0 { 634 a = append(a, v) 635 } 636 } 637 *dst = a 638 } 639 return m 640 } 641 642 // IntSetUnion calculates between multiple collections: set1 ∪ set2 ∪ others... 643 // This method does not change the existing slices, but instead returns a new slice. 644 func IntSetUnion(set1, set2 []int, others ...[]int) []int { 645 m := make(map[int]struct{}, len(set1)+len(set2)) 646 r := make([]int, 0, len(m)) 647 for _, set := range append([][]int{set1, set2}, others...) { 648 for _, v := range set { 649 _, ok := m[v] 650 if ok { 651 continue 652 } 653 r = append(r, v) 654 m[v] = struct{}{} 655 } 656 } 657 return r 658 } 659 660 // IntSetIntersect calculates between multiple collections: set1 ∩ set2 ∩ others... 661 // This method does not change the existing slices, but instead returns a new slice. 662 func IntSetIntersect(set1, set2 []int, others ...[]int) []int { 663 sets := append([][]int{set2}, others...) 664 setsCount := make([]map[int]int, len(sets)) 665 for k, v := range sets { 666 setsCount[k] = intsDistinct(v, nil) 667 } 668 m := make(map[int]struct{}, len(set1)) 669 r := make([]int, 0, len(m)) 670 L: 671 for _, v := range set1 { 672 if _, ok := m[v]; ok { 673 continue 674 } 675 m[v] = struct{}{} 676 for _, m2 := range setsCount { 677 if m2[v] == 0 { 678 continue L 679 } 680 } 681 r = append(r, v) 682 } 683 return r 684 } 685 686 // IntSetDifference calculates between multiple collections: set1 - set2 - others... 687 // This method does not change the existing slices, but instead returns a new slice. 688 func IntSetDifference(set1, set2 []int, others ...[]int) []int { 689 m := make(map[int]struct{}, len(set1)) 690 r := make([]int, 0, len(set1)) 691 sets := append([][]int{set2}, others...) 692 for _, v := range sets { 693 inter := IntSetIntersect(set1, v) 694 for _, v := range inter { 695 m[v] = struct{}{} 696 } 697 } 698 for _, v := range set1 { 699 if _, ok := m[v]; !ok { 700 r = append(r, v) 701 m[v] = struct{}{} 702 } 703 } 704 return r 705 }