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