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