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