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