github.com/gogf/gf@v1.16.9/container/garray/garray_normal_int.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package garray 8 9 import ( 10 "bytes" 11 "fmt" 12 "github.com/gogf/gf/errors/gcode" 13 "github.com/gogf/gf/errors/gerror" 14 "github.com/gogf/gf/internal/json" 15 "math" 16 "sort" 17 18 "github.com/gogf/gf/internal/rwmutex" 19 "github.com/gogf/gf/util/gconv" 20 "github.com/gogf/gf/util/grand" 21 ) 22 23 // IntArray is a golang int array with rich features. 24 // It contains a concurrent-safe/unsafe switch, which should be set 25 // when its initialization and cannot be changed then. 26 type IntArray struct { 27 mu rwmutex.RWMutex 28 array []int 29 } 30 31 // NewIntArray creates and returns an empty array. 32 // The parameter `safe` is used to specify whether using array in concurrent-safety, 33 // which is false in default. 34 func NewIntArray(safe ...bool) *IntArray { 35 return NewIntArraySize(0, 0, safe...) 36 } 37 38 // NewIntArraySize create and returns an array with given size and cap. 39 // The parameter `safe` is used to specify whether using array in concurrent-safety, 40 // which is false in default. 41 func NewIntArraySize(size int, cap int, safe ...bool) *IntArray { 42 return &IntArray{ 43 mu: rwmutex.Create(safe...), 44 array: make([]int, size, cap), 45 } 46 } 47 48 // NewIntArrayRange creates and returns a array by a range from `start` to `end` 49 // with step value `step`. 50 func NewIntArrayRange(start, end, step int, safe ...bool) *IntArray { 51 if step == 0 { 52 panic(fmt.Sprintf(`invalid step value: %d`, step)) 53 } 54 slice := make([]int, (end-start+1)/step) 55 index := 0 56 for i := start; i <= end; i += step { 57 slice[index] = i 58 index++ 59 } 60 return NewIntArrayFrom(slice, safe...) 61 } 62 63 // NewIntArrayFrom creates and returns an array with given slice `array`. 64 // The parameter `safe` is used to specify whether using array in concurrent-safety, 65 // which is false in default. 66 func NewIntArrayFrom(array []int, safe ...bool) *IntArray { 67 return &IntArray{ 68 mu: rwmutex.Create(safe...), 69 array: array, 70 } 71 } 72 73 // NewIntArrayFromCopy creates and returns an array from a copy of given slice `array`. 74 // The parameter `safe` is used to specify whether using array in concurrent-safety, 75 // which is false in default. 76 func NewIntArrayFromCopy(array []int, safe ...bool) *IntArray { 77 newArray := make([]int, len(array)) 78 copy(newArray, array) 79 return &IntArray{ 80 mu: rwmutex.Create(safe...), 81 array: newArray, 82 } 83 } 84 85 // At returns the value by the specified index. 86 // If the given `index` is out of range of the array, it returns `0`. 87 func (a *IntArray) At(index int) (value int) { 88 value, _ = a.Get(index) 89 return 90 } 91 92 // Get returns the value by the specified index. 93 // If the given `index` is out of range of the array, the `found` is false. 94 func (a *IntArray) Get(index int) (value int, found bool) { 95 a.mu.RLock() 96 defer a.mu.RUnlock() 97 if index < 0 || index >= len(a.array) { 98 return 0, false 99 } 100 return a.array[index], true 101 } 102 103 // Set sets value to specified index. 104 func (a *IntArray) Set(index int, value int) error { 105 a.mu.Lock() 106 defer a.mu.Unlock() 107 if index < 0 || index >= len(a.array) { 108 return gerror.NewCodef(gcode.CodeInvalidParameter, "index %d out of array range %d", index, len(a.array)) 109 } 110 a.array[index] = value 111 return nil 112 } 113 114 // SetArray sets the underlying slice array with the given `array`. 115 func (a *IntArray) SetArray(array []int) *IntArray { 116 a.mu.Lock() 117 defer a.mu.Unlock() 118 a.array = array 119 return a 120 } 121 122 // Replace replaces the array items by given `array` from the beginning of array. 123 func (a *IntArray) Replace(array []int) *IntArray { 124 a.mu.Lock() 125 defer a.mu.Unlock() 126 max := len(array) 127 if max > len(a.array) { 128 max = len(a.array) 129 } 130 for i := 0; i < max; i++ { 131 a.array[i] = array[i] 132 } 133 return a 134 } 135 136 // Sum returns the sum of values in an array. 137 func (a *IntArray) Sum() (sum int) { 138 a.mu.RLock() 139 defer a.mu.RUnlock() 140 for _, v := range a.array { 141 sum += v 142 } 143 return 144 } 145 146 // Sort sorts the array in increasing order. 147 // The parameter `reverse` controls whether sort in increasing order(default) or decreasing order. 148 func (a *IntArray) Sort(reverse ...bool) *IntArray { 149 a.mu.Lock() 150 defer a.mu.Unlock() 151 if len(reverse) > 0 && reverse[0] { 152 sort.Slice(a.array, func(i, j int) bool { 153 return a.array[i] >= a.array[j] 154 }) 155 } else { 156 sort.Ints(a.array) 157 } 158 return a 159 } 160 161 // SortFunc sorts the array by custom function `less`. 162 func (a *IntArray) SortFunc(less func(v1, v2 int) bool) *IntArray { 163 a.mu.Lock() 164 defer a.mu.Unlock() 165 sort.Slice(a.array, func(i, j int) bool { 166 return less(a.array[i], a.array[j]) 167 }) 168 return a 169 } 170 171 // InsertBefore inserts the `value` to the front of `index`. 172 func (a *IntArray) InsertBefore(index int, value int) error { 173 a.mu.Lock() 174 defer a.mu.Unlock() 175 if index < 0 || index >= len(a.array) { 176 return gerror.NewCodef(gcode.CodeInvalidParameter, "index %d out of array range %d", index, len(a.array)) 177 } 178 rear := append([]int{}, a.array[index:]...) 179 a.array = append(a.array[0:index], value) 180 a.array = append(a.array, rear...) 181 return nil 182 } 183 184 // InsertAfter inserts the `value` to the back of `index`. 185 func (a *IntArray) InsertAfter(index int, value int) error { 186 a.mu.Lock() 187 defer a.mu.Unlock() 188 if index < 0 || index >= len(a.array) { 189 return gerror.NewCodef(gcode.CodeInvalidParameter, "index %d out of array range %d", index, len(a.array)) 190 } 191 rear := append([]int{}, a.array[index+1:]...) 192 a.array = append(a.array[0:index+1], value) 193 a.array = append(a.array, rear...) 194 return nil 195 } 196 197 // Remove removes an item by index. 198 // If the given `index` is out of range of the array, the `found` is false. 199 func (a *IntArray) Remove(index int) (value int, found bool) { 200 a.mu.Lock() 201 defer a.mu.Unlock() 202 return a.doRemoveWithoutLock(index) 203 } 204 205 // doRemoveWithoutLock removes an item by index without lock. 206 func (a *IntArray) doRemoveWithoutLock(index int) (value int, found bool) { 207 if index < 0 || index >= len(a.array) { 208 return 0, false 209 } 210 // Determine array boundaries when deleting to improve deletion efficiency. 211 if index == 0 { 212 value := a.array[0] 213 a.array = a.array[1:] 214 return value, true 215 } else if index == len(a.array)-1 { 216 value := a.array[index] 217 a.array = a.array[:index] 218 return value, true 219 } 220 // If it is a non-boundary delete, 221 // it will involve the creation of an array, 222 // then the deletion is less efficient. 223 value = a.array[index] 224 a.array = append(a.array[:index], a.array[index+1:]...) 225 return value, true 226 } 227 228 // RemoveValue removes an item by value. 229 // It returns true if value is found in the array, or else false if not found. 230 func (a *IntArray) RemoveValue(value int) bool { 231 if i := a.Search(value); i != -1 { 232 _, found := a.Remove(i) 233 return found 234 } 235 return false 236 } 237 238 // PushLeft pushes one or multiple items to the beginning of array. 239 func (a *IntArray) PushLeft(value ...int) *IntArray { 240 a.mu.Lock() 241 a.array = append(value, a.array...) 242 a.mu.Unlock() 243 return a 244 } 245 246 // PushRight pushes one or multiple items to the end of array. 247 // It equals to Append. 248 func (a *IntArray) PushRight(value ...int) *IntArray { 249 a.mu.Lock() 250 a.array = append(a.array, value...) 251 a.mu.Unlock() 252 return a 253 } 254 255 // PopLeft pops and returns an item from the beginning of array. 256 // Note that if the array is empty, the `found` is false. 257 func (a *IntArray) PopLeft() (value int, found bool) { 258 a.mu.Lock() 259 defer a.mu.Unlock() 260 if len(a.array) == 0 { 261 return 0, false 262 } 263 value = a.array[0] 264 a.array = a.array[1:] 265 return value, true 266 } 267 268 // PopRight pops and returns an item from the end of array. 269 // Note that if the array is empty, the `found` is false. 270 func (a *IntArray) PopRight() (value int, found bool) { 271 a.mu.Lock() 272 defer a.mu.Unlock() 273 index := len(a.array) - 1 274 if index < 0 { 275 return 0, false 276 } 277 value = a.array[index] 278 a.array = a.array[:index] 279 return value, true 280 } 281 282 // PopRand randomly pops and return an item out of array. 283 // Note that if the array is empty, the `found` is false. 284 func (a *IntArray) PopRand() (value int, found bool) { 285 a.mu.Lock() 286 defer a.mu.Unlock() 287 return a.doRemoveWithoutLock(grand.Intn(len(a.array))) 288 } 289 290 // PopRands randomly pops and returns `size` items out of array. 291 // If the given `size` is greater than size of the array, it returns all elements of the array. 292 // Note that if given `size` <= 0 or the array is empty, it returns nil. 293 func (a *IntArray) PopRands(size int) []int { 294 a.mu.Lock() 295 defer a.mu.Unlock() 296 if size <= 0 || len(a.array) == 0 { 297 return nil 298 } 299 if size >= len(a.array) { 300 size = len(a.array) 301 } 302 array := make([]int, size) 303 for i := 0; i < size; i++ { 304 array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array))) 305 } 306 return array 307 } 308 309 // PopLefts pops and returns `size` items from the beginning of array. 310 // If the given `size` is greater than size of the array, it returns all elements of the array. 311 // Note that if given `size` <= 0 or the array is empty, it returns nil. 312 func (a *IntArray) PopLefts(size int) []int { 313 a.mu.Lock() 314 defer a.mu.Unlock() 315 if size <= 0 || len(a.array) == 0 { 316 return nil 317 } 318 if size >= len(a.array) { 319 array := a.array 320 a.array = a.array[:0] 321 return array 322 } 323 value := a.array[0:size] 324 a.array = a.array[size:] 325 return value 326 } 327 328 // PopRights pops and returns `size` items from the end of array. 329 // If the given `size` is greater than size of the array, it returns all elements of the array. 330 // Note that if given `size` <= 0 or the array is empty, it returns nil. 331 func (a *IntArray) PopRights(size int) []int { 332 a.mu.Lock() 333 defer a.mu.Unlock() 334 if size <= 0 || len(a.array) == 0 { 335 return nil 336 } 337 index := len(a.array) - size 338 if index <= 0 { 339 array := a.array 340 a.array = a.array[:0] 341 return array 342 } 343 value := a.array[index:] 344 a.array = a.array[:index] 345 return value 346 } 347 348 // Range picks and returns items by range, like array[start:end]. 349 // Notice, if in concurrent-safe usage, it returns a copy of slice; 350 // else a pointer to the underlying data. 351 // 352 // If `end` is negative, then the offset will start from the end of array. 353 // If `end` is omitted, then the sequence will have everything from start up 354 // until the end of the array. 355 func (a *IntArray) Range(start int, end ...int) []int { 356 a.mu.RLock() 357 defer a.mu.RUnlock() 358 offsetEnd := len(a.array) 359 if len(end) > 0 && end[0] < offsetEnd { 360 offsetEnd = end[0] 361 } 362 if start > offsetEnd { 363 return nil 364 } 365 if start < 0 { 366 start = 0 367 } 368 array := ([]int)(nil) 369 if a.mu.IsSafe() { 370 array = make([]int, offsetEnd-start) 371 copy(array, a.array[start:offsetEnd]) 372 } else { 373 array = a.array[start:offsetEnd] 374 } 375 return array 376 } 377 378 // SubSlice returns a slice of elements from the array as specified 379 // by the `offset` and `size` parameters. 380 // If in concurrent safe usage, it returns a copy of the slice; else a pointer. 381 // 382 // If offset is non-negative, the sequence will start at that offset in the array. 383 // If offset is negative, the sequence will start that far from the end of the array. 384 // 385 // If length is given and is positive, then the sequence will have up to that many elements in it. 386 // If the array is shorter than the length, then only the available array elements will be present. 387 // If length is given and is negative then the sequence will stop that many elements from the end of the array. 388 // If it is omitted, then the sequence will have everything from offset up until the end of the array. 389 // 390 // Any possibility crossing the left border of array, it will fail. 391 func (a *IntArray) SubSlice(offset int, length ...int) []int { 392 a.mu.RLock() 393 defer a.mu.RUnlock() 394 size := len(a.array) 395 if len(length) > 0 { 396 size = length[0] 397 } 398 if offset > len(a.array) { 399 return nil 400 } 401 if offset < 0 { 402 offset = len(a.array) + offset 403 if offset < 0 { 404 return nil 405 } 406 } 407 if size < 0 { 408 offset += size 409 size = -size 410 if offset < 0 { 411 return nil 412 } 413 } 414 end := offset + size 415 if end > len(a.array) { 416 end = len(a.array) 417 size = len(a.array) - offset 418 } 419 if a.mu.IsSafe() { 420 s := make([]int, size) 421 copy(s, a.array[offset:]) 422 return s 423 } else { 424 return a.array[offset:end] 425 } 426 } 427 428 // Append is alias of PushRight,please See PushRight. 429 func (a *IntArray) Append(value ...int) *IntArray { 430 a.mu.Lock() 431 a.array = append(a.array, value...) 432 a.mu.Unlock() 433 return a 434 } 435 436 // Len returns the length of array. 437 func (a *IntArray) Len() int { 438 a.mu.RLock() 439 length := len(a.array) 440 a.mu.RUnlock() 441 return length 442 } 443 444 // Slice returns the underlying data of array. 445 // Note that, if it's in concurrent-safe usage, it returns a copy of underlying data, 446 // or else a pointer to the underlying data. 447 func (a *IntArray) Slice() []int { 448 array := ([]int)(nil) 449 if a.mu.IsSafe() { 450 a.mu.RLock() 451 defer a.mu.RUnlock() 452 array = make([]int, len(a.array)) 453 copy(array, a.array) 454 } else { 455 array = a.array 456 } 457 return array 458 } 459 460 // Interfaces returns current array as []interface{}. 461 func (a *IntArray) Interfaces() []interface{} { 462 a.mu.RLock() 463 defer a.mu.RUnlock() 464 array := make([]interface{}, len(a.array)) 465 for k, v := range a.array { 466 array[k] = v 467 } 468 return array 469 } 470 471 // Clone returns a new array, which is a copy of current array. 472 func (a *IntArray) Clone() (newArray *IntArray) { 473 a.mu.RLock() 474 array := make([]int, len(a.array)) 475 copy(array, a.array) 476 a.mu.RUnlock() 477 return NewIntArrayFrom(array, a.mu.IsSafe()) 478 } 479 480 // Clear deletes all items of current array. 481 func (a *IntArray) Clear() *IntArray { 482 a.mu.Lock() 483 if len(a.array) > 0 { 484 a.array = make([]int, 0) 485 } 486 a.mu.Unlock() 487 return a 488 } 489 490 // Contains checks whether a value exists in the array. 491 func (a *IntArray) Contains(value int) bool { 492 return a.Search(value) != -1 493 } 494 495 // Search searches array by `value`, returns the index of `value`, 496 // or returns -1 if not exists. 497 func (a *IntArray) Search(value int) int { 498 a.mu.RLock() 499 defer a.mu.RUnlock() 500 if len(a.array) == 0 { 501 return -1 502 } 503 result := -1 504 for index, v := range a.array { 505 if v == value { 506 result = index 507 break 508 } 509 } 510 return result 511 } 512 513 // Unique uniques the array, clear repeated items. 514 // Example: [1,1,2,3,2] -> [1,2,3] 515 func (a *IntArray) Unique() *IntArray { 516 a.mu.Lock() 517 for i := 0; i < len(a.array)-1; i++ { 518 for j := i + 1; j < len(a.array); { 519 if a.array[i] == a.array[j] { 520 a.array = append(a.array[:j], a.array[j+1:]...) 521 } else { 522 j++ 523 } 524 } 525 } 526 a.mu.Unlock() 527 return a 528 } 529 530 // LockFunc locks writing by callback function `f`. 531 func (a *IntArray) LockFunc(f func(array []int)) *IntArray { 532 a.mu.Lock() 533 defer a.mu.Unlock() 534 f(a.array) 535 return a 536 } 537 538 // RLockFunc locks reading by callback function `f`. 539 func (a *IntArray) RLockFunc(f func(array []int)) *IntArray { 540 a.mu.RLock() 541 defer a.mu.RUnlock() 542 f(a.array) 543 return a 544 } 545 546 // Merge merges `array` into current array. 547 // The parameter `array` can be any garray or slice type. 548 // The difference between Merge and Append is Append supports only specified slice type, 549 // but Merge supports more parameter types. 550 func (a *IntArray) Merge(array interface{}) *IntArray { 551 return a.Append(gconv.Ints(array)...) 552 } 553 554 // Fill fills an array with num entries of the value `value`, 555 // keys starting at the `startIndex` parameter. 556 func (a *IntArray) Fill(startIndex int, num int, value int) error { 557 a.mu.Lock() 558 defer a.mu.Unlock() 559 if startIndex < 0 || startIndex > len(a.array) { 560 return gerror.NewCodef(gcode.CodeInvalidParameter, "index %d out of array range %d", startIndex, len(a.array)) 561 } 562 for i := startIndex; i < startIndex+num; i++ { 563 if i > len(a.array)-1 { 564 a.array = append(a.array, value) 565 } else { 566 a.array[i] = value 567 } 568 } 569 return nil 570 } 571 572 // Chunk splits an array into multiple arrays, 573 // the size of each array is determined by `size`. 574 // The last chunk may contain less than size elements. 575 func (a *IntArray) Chunk(size int) [][]int { 576 if size < 1 { 577 return nil 578 } 579 a.mu.RLock() 580 defer a.mu.RUnlock() 581 length := len(a.array) 582 chunks := int(math.Ceil(float64(length) / float64(size))) 583 var n [][]int 584 for i, end := 0, 0; chunks > 0; chunks-- { 585 end = (i + 1) * size 586 if end > length { 587 end = length 588 } 589 n = append(n, a.array[i*size:end]) 590 i++ 591 } 592 return n 593 } 594 595 // Pad pads array to the specified length with `value`. 596 // If size is positive then the array is padded on the right, or negative on the left. 597 // If the absolute value of `size` is less than or equal to the length of the array 598 // then no padding takes place. 599 func (a *IntArray) Pad(size int, value int) *IntArray { 600 a.mu.Lock() 601 defer a.mu.Unlock() 602 if size == 0 || (size > 0 && size < len(a.array)) || (size < 0 && size > -len(a.array)) { 603 return a 604 } 605 n := size 606 if size < 0 { 607 n = -size 608 } 609 n -= len(a.array) 610 tmp := make([]int, n) 611 for i := 0; i < n; i++ { 612 tmp[i] = value 613 } 614 if size > 0 { 615 a.array = append(a.array, tmp...) 616 } else { 617 a.array = append(tmp, a.array...) 618 } 619 return a 620 } 621 622 // Rand randomly returns one item from array(no deleting). 623 func (a *IntArray) Rand() (value int, found bool) { 624 a.mu.RLock() 625 defer a.mu.RUnlock() 626 if len(a.array) == 0 { 627 return 0, false 628 } 629 return a.array[grand.Intn(len(a.array))], true 630 } 631 632 // Rands randomly returns `size` items from array(no deleting). 633 func (a *IntArray) Rands(size int) []int { 634 a.mu.RLock() 635 defer a.mu.RUnlock() 636 if size <= 0 || len(a.array) == 0 { 637 return nil 638 } 639 array := make([]int, size) 640 for i := 0; i < size; i++ { 641 array[i] = a.array[grand.Intn(len(a.array))] 642 } 643 return array 644 } 645 646 // Shuffle randomly shuffles the array. 647 func (a *IntArray) Shuffle() *IntArray { 648 a.mu.Lock() 649 defer a.mu.Unlock() 650 for i, v := range grand.Perm(len(a.array)) { 651 a.array[i], a.array[v] = a.array[v], a.array[i] 652 } 653 return a 654 } 655 656 // Reverse makes array with elements in reverse order. 657 func (a *IntArray) Reverse() *IntArray { 658 a.mu.Lock() 659 defer a.mu.Unlock() 660 for i, j := 0, len(a.array)-1; i < j; i, j = i+1, j-1 { 661 a.array[i], a.array[j] = a.array[j], a.array[i] 662 } 663 return a 664 } 665 666 // Join joins array elements with a string `glue`. 667 func (a *IntArray) Join(glue string) string { 668 a.mu.RLock() 669 defer a.mu.RUnlock() 670 if len(a.array) == 0 { 671 return "" 672 } 673 buffer := bytes.NewBuffer(nil) 674 for k, v := range a.array { 675 buffer.WriteString(gconv.String(v)) 676 if k != len(a.array)-1 { 677 buffer.WriteString(glue) 678 } 679 } 680 return buffer.String() 681 } 682 683 // CountValues counts the number of occurrences of all values in the array. 684 func (a *IntArray) CountValues() map[int]int { 685 m := make(map[int]int) 686 a.mu.RLock() 687 defer a.mu.RUnlock() 688 for _, v := range a.array { 689 m[v]++ 690 } 691 return m 692 } 693 694 // Iterator is alias of IteratorAsc. 695 func (a *IntArray) Iterator(f func(k int, v int) bool) { 696 a.IteratorAsc(f) 697 } 698 699 // IteratorAsc iterates the array readonly in ascending order with given callback function `f`. 700 // If `f` returns true, then it continues iterating; or false to stop. 701 func (a *IntArray) IteratorAsc(f func(k int, v int) bool) { 702 a.mu.RLock() 703 defer a.mu.RUnlock() 704 for k, v := range a.array { 705 if !f(k, v) { 706 break 707 } 708 } 709 } 710 711 // IteratorDesc iterates the array readonly in descending order with given callback function `f`. 712 // If `f` returns true, then it continues iterating; or false to stop. 713 func (a *IntArray) IteratorDesc(f func(k int, v int) bool) { 714 a.mu.RLock() 715 defer a.mu.RUnlock() 716 for i := len(a.array) - 1; i >= 0; i-- { 717 if !f(i, a.array[i]) { 718 break 719 } 720 } 721 } 722 723 // String returns current array as a string, which implements like json.Marshal does. 724 func (a *IntArray) String() string { 725 return "[" + a.Join(",") + "]" 726 } 727 728 // MarshalJSON implements the interface MarshalJSON for json.Marshal. 729 // Note that do not use pointer as its receiver here. 730 func (a IntArray) MarshalJSON() ([]byte, error) { 731 a.mu.RLock() 732 defer a.mu.RUnlock() 733 return json.Marshal(a.array) 734 } 735 736 // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal. 737 func (a *IntArray) UnmarshalJSON(b []byte) error { 738 if a.array == nil { 739 a.array = make([]int, 0) 740 } 741 a.mu.Lock() 742 defer a.mu.Unlock() 743 if err := json.UnmarshalUseNumber(b, &a.array); err != nil { 744 return err 745 } 746 return nil 747 } 748 749 // UnmarshalValue is an interface implement which sets any type of value for array. 750 func (a *IntArray) UnmarshalValue(value interface{}) error { 751 a.mu.Lock() 752 defer a.mu.Unlock() 753 switch value.(type) { 754 case string, []byte: 755 return json.UnmarshalUseNumber(gconv.Bytes(value), &a.array) 756 default: 757 a.array = gconv.SliceInt(value) 758 } 759 return nil 760 } 761 762 // FilterEmpty removes all zero value of the array. 763 func (a *IntArray) FilterEmpty() *IntArray { 764 a.mu.Lock() 765 defer a.mu.Unlock() 766 for i := 0; i < len(a.array); { 767 if a.array[i] == 0 { 768 a.array = append(a.array[:i], a.array[i+1:]...) 769 } else { 770 i++ 771 } 772 } 773 return a 774 } 775 776 // Walk applies a user supplied function `f` to every item of array. 777 func (a *IntArray) Walk(f func(value int) int) *IntArray { 778 a.mu.Lock() 779 defer a.mu.Unlock() 780 for i, v := range a.array { 781 a.array[i] = f(v) 782 } 783 return a 784 } 785 786 // IsEmpty checks whether the array is empty. 787 func (a *IntArray) IsEmpty() bool { 788 return a.Len() == 0 789 }