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