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