github.com/wangyougui/gf/v2@v2.6.5/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/wangyougui/gf. 6 7 package garray 8 9 import ( 10 "bytes" 11 "fmt" 12 "math" 13 "sort" 14 15 "github.com/wangyougui/gf/v2/errors/gcode" 16 "github.com/wangyougui/gf/v2/errors/gerror" 17 "github.com/wangyougui/gf/v2/internal/json" 18 "github.com/wangyougui/gf/v2/internal/rwmutex" 19 "github.com/wangyougui/gf/v2/util/gconv" 20 "github.com/wangyougui/gf/v2/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 an 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, 0) 55 index := 0 56 for i := start; i <= end; i += step { 57 slice = append(slice, 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 `values` to the front of `index`. 172 func (a *IntArray) InsertBefore(index int, values ...int) error { 173 a.mu.Lock() 174 defer a.mu.Unlock() 175 if index < 0 || index >= len(a.array) { 176 return gerror.NewCodef( 177 gcode.CodeInvalidParameter, 178 "index %d out of array range %d", 179 index, len(a.array), 180 ) 181 } 182 rear := append([]int{}, a.array[index:]...) 183 a.array = append(a.array[0:index], values...) 184 a.array = append(a.array, rear...) 185 return nil 186 } 187 188 // InsertAfter inserts the `value` to the back of `index`. 189 func (a *IntArray) InsertAfter(index int, values ...int) error { 190 a.mu.Lock() 191 defer a.mu.Unlock() 192 if index < 0 || index >= len(a.array) { 193 return gerror.NewCodef( 194 gcode.CodeInvalidParameter, 195 "index %d out of array range %d", 196 index, len(a.array), 197 ) 198 } 199 rear := append([]int{}, a.array[index+1:]...) 200 a.array = append(a.array[0:index+1], values...) 201 a.array = append(a.array, rear...) 202 return nil 203 } 204 205 // Remove removes an item by index. 206 // If the given `index` is out of range of the array, the `found` is false. 207 func (a *IntArray) Remove(index int) (value int, found bool) { 208 a.mu.Lock() 209 defer a.mu.Unlock() 210 return a.doRemoveWithoutLock(index) 211 } 212 213 // doRemoveWithoutLock removes an item by index without lock. 214 func (a *IntArray) doRemoveWithoutLock(index int) (value int, found bool) { 215 if index < 0 || index >= len(a.array) { 216 return 0, false 217 } 218 // Determine array boundaries when deleting to improve deletion efficiency. 219 if index == 0 { 220 value := a.array[0] 221 a.array = a.array[1:] 222 return value, true 223 } else if index == len(a.array)-1 { 224 value := a.array[index] 225 a.array = a.array[:index] 226 return value, true 227 } 228 // If it is a non-boundary delete, 229 // it will involve the creation of an array, 230 // then the deletion is less efficient. 231 value = a.array[index] 232 a.array = append(a.array[:index], a.array[index+1:]...) 233 return value, true 234 } 235 236 // RemoveValue removes an item by value. 237 // It returns true if value is found in the array, or else false if not found. 238 func (a *IntArray) RemoveValue(value int) bool { 239 a.mu.Lock() 240 defer a.mu.Unlock() 241 if i := a.doSearchWithoutLock(value); i != -1 { 242 a.doRemoveWithoutLock(i) 243 return true 244 } 245 return false 246 } 247 248 // RemoveValues removes multiple items by `values`. 249 func (a *IntArray) RemoveValues(values ...int) { 250 a.mu.Lock() 251 defer a.mu.Unlock() 252 for _, value := range values { 253 if i := a.doSearchWithoutLock(value); i != -1 { 254 a.doRemoveWithoutLock(i) 255 } 256 } 257 } 258 259 // PushLeft pushes one or multiple items to the beginning of array. 260 func (a *IntArray) PushLeft(value ...int) *IntArray { 261 a.mu.Lock() 262 a.array = append(value, a.array...) 263 a.mu.Unlock() 264 return a 265 } 266 267 // PushRight pushes one or multiple items to the end of array. 268 // It equals to Append. 269 func (a *IntArray) PushRight(value ...int) *IntArray { 270 a.mu.Lock() 271 a.array = append(a.array, value...) 272 a.mu.Unlock() 273 return a 274 } 275 276 // PopLeft pops and returns an item from the beginning of array. 277 // Note that if the array is empty, the `found` is false. 278 func (a *IntArray) PopLeft() (value int, found bool) { 279 a.mu.Lock() 280 defer a.mu.Unlock() 281 if len(a.array) == 0 { 282 return 0, false 283 } 284 value = a.array[0] 285 a.array = a.array[1:] 286 return value, true 287 } 288 289 // PopRight pops and returns an item from the end of array. 290 // Note that if the array is empty, the `found` is false. 291 func (a *IntArray) PopRight() (value int, found bool) { 292 a.mu.Lock() 293 defer a.mu.Unlock() 294 index := len(a.array) - 1 295 if index < 0 { 296 return 0, false 297 } 298 value = a.array[index] 299 a.array = a.array[:index] 300 return value, true 301 } 302 303 // PopRand randomly pops and return an item out of array. 304 // Note that if the array is empty, the `found` is false. 305 func (a *IntArray) PopRand() (value int, found bool) { 306 a.mu.Lock() 307 defer a.mu.Unlock() 308 return a.doRemoveWithoutLock(grand.Intn(len(a.array))) 309 } 310 311 // PopRands randomly pops and returns `size` items out of array. 312 // If the given `size` is greater than size of the array, it returns all elements of the array. 313 // Note that if given `size` <= 0 or the array is empty, it returns nil. 314 func (a *IntArray) PopRands(size int) []int { 315 a.mu.Lock() 316 defer a.mu.Unlock() 317 if size <= 0 || len(a.array) == 0 { 318 return nil 319 } 320 if size >= len(a.array) { 321 size = len(a.array) 322 } 323 array := make([]int, size) 324 for i := 0; i < size; i++ { 325 array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array))) 326 } 327 return array 328 } 329 330 // PopLefts pops and returns `size` items from the beginning of array. 331 // If the given `size` is greater than size of the array, it returns all elements of the array. 332 // Note that if given `size` <= 0 or the array is empty, it returns nil. 333 func (a *IntArray) PopLefts(size int) []int { 334 a.mu.Lock() 335 defer a.mu.Unlock() 336 if size <= 0 || len(a.array) == 0 { 337 return nil 338 } 339 if size >= len(a.array) { 340 array := a.array 341 a.array = a.array[:0] 342 return array 343 } 344 value := a.array[0:size] 345 a.array = a.array[size:] 346 return value 347 } 348 349 // PopRights pops and returns `size` items from the end of array. 350 // If the given `size` is greater than size of the array, it returns all elements of the array. 351 // Note that if given `size` <= 0 or the array is empty, it returns nil. 352 func (a *IntArray) PopRights(size int) []int { 353 a.mu.Lock() 354 defer a.mu.Unlock() 355 if size <= 0 || len(a.array) == 0 { 356 return nil 357 } 358 index := len(a.array) - size 359 if index <= 0 { 360 array := a.array 361 a.array = a.array[:0] 362 return array 363 } 364 value := a.array[index:] 365 a.array = a.array[:index] 366 return value 367 } 368 369 // Range picks and returns items by range, like array[start:end]. 370 // Notice, if in concurrent-safe usage, it returns a copy of slice; 371 // else a pointer to the underlying data. 372 // 373 // If `end` is negative, then the offset will start from the end of array. 374 // If `end` is omitted, then the sequence will have everything from start up 375 // until the end of the array. 376 func (a *IntArray) Range(start int, end ...int) []int { 377 a.mu.RLock() 378 defer a.mu.RUnlock() 379 offsetEnd := len(a.array) 380 if len(end) > 0 && end[0] < offsetEnd { 381 offsetEnd = end[0] 382 } 383 if start > offsetEnd { 384 return nil 385 } 386 if start < 0 { 387 start = 0 388 } 389 array := ([]int)(nil) 390 if a.mu.IsSafe() { 391 array = make([]int, offsetEnd-start) 392 copy(array, a.array[start:offsetEnd]) 393 } else { 394 array = a.array[start:offsetEnd] 395 } 396 return array 397 } 398 399 // SubSlice returns a slice of elements from the array as specified 400 // by the `offset` and `size` parameters. 401 // If in concurrent safe usage, it returns a copy of the slice; else a pointer. 402 // 403 // If offset is non-negative, the sequence will start at that offset in the array. 404 // If offset is negative, the sequence will start that far from the end of the array. 405 // 406 // If length is given and is positive, then the sequence will have up to that many elements in it. 407 // If the array is shorter than the length, then only the available array elements will be present. 408 // If length is given and is negative then the sequence will stop that many elements from the end of the array. 409 // If it is omitted, then the sequence will have everything from offset up until the end of the array. 410 // 411 // Any possibility crossing the left border of array, it will fail. 412 func (a *IntArray) SubSlice(offset int, length ...int) []int { 413 a.mu.RLock() 414 defer a.mu.RUnlock() 415 size := len(a.array) 416 if len(length) > 0 { 417 size = length[0] 418 } 419 if offset > len(a.array) { 420 return nil 421 } 422 if offset < 0 { 423 offset = len(a.array) + offset 424 if offset < 0 { 425 return nil 426 } 427 } 428 if size < 0 { 429 offset += size 430 size = -size 431 if offset < 0 { 432 return nil 433 } 434 } 435 end := offset + size 436 if end > len(a.array) { 437 end = len(a.array) 438 size = len(a.array) - offset 439 } 440 if a.mu.IsSafe() { 441 s := make([]int, size) 442 copy(s, a.array[offset:]) 443 return s 444 } else { 445 return a.array[offset:end] 446 } 447 } 448 449 // Append is alias of PushRight,please See PushRight. 450 func (a *IntArray) Append(value ...int) *IntArray { 451 a.mu.Lock() 452 a.array = append(a.array, value...) 453 a.mu.Unlock() 454 return a 455 } 456 457 // Len returns the length of array. 458 func (a *IntArray) Len() int { 459 a.mu.RLock() 460 length := len(a.array) 461 a.mu.RUnlock() 462 return length 463 } 464 465 // Slice returns the underlying data of array. 466 // Note that, if it's in concurrent-safe usage, it returns a copy of underlying data, 467 // or else a pointer to the underlying data. 468 func (a *IntArray) Slice() []int { 469 array := ([]int)(nil) 470 if a.mu.IsSafe() { 471 a.mu.RLock() 472 defer a.mu.RUnlock() 473 array = make([]int, len(a.array)) 474 copy(array, a.array) 475 } else { 476 array = a.array 477 } 478 return array 479 } 480 481 // Interfaces returns current array as []interface{}. 482 func (a *IntArray) Interfaces() []interface{} { 483 a.mu.RLock() 484 defer a.mu.RUnlock() 485 array := make([]interface{}, len(a.array)) 486 for k, v := range a.array { 487 array[k] = v 488 } 489 return array 490 } 491 492 // Clone returns a new array, which is a copy of current array. 493 func (a *IntArray) Clone() (newArray *IntArray) { 494 a.mu.RLock() 495 array := make([]int, len(a.array)) 496 copy(array, a.array) 497 a.mu.RUnlock() 498 return NewIntArrayFrom(array, a.mu.IsSafe()) 499 } 500 501 // Clear deletes all items of current array. 502 func (a *IntArray) Clear() *IntArray { 503 a.mu.Lock() 504 if len(a.array) > 0 { 505 a.array = make([]int, 0) 506 } 507 a.mu.Unlock() 508 return a 509 } 510 511 // Contains checks whether a value exists in the array. 512 func (a *IntArray) Contains(value int) bool { 513 return a.Search(value) != -1 514 } 515 516 // Search searches array by `value`, returns the index of `value`, 517 // or returns -1 if not exists. 518 func (a *IntArray) Search(value int) int { 519 a.mu.RLock() 520 defer a.mu.RUnlock() 521 return a.doSearchWithoutLock(value) 522 } 523 524 func (a *IntArray) doSearchWithoutLock(value int) int { 525 if len(a.array) == 0 { 526 return -1 527 } 528 result := -1 529 for index, v := range a.array { 530 if v == value { 531 result = index 532 break 533 } 534 } 535 return result 536 } 537 538 // Unique uniques the array, clear repeated items. 539 // Example: [1,1,2,3,2] -> [1,2,3] 540 func (a *IntArray) Unique() *IntArray { 541 a.mu.Lock() 542 defer a.mu.Unlock() 543 if len(a.array) == 0 { 544 return a 545 } 546 var ( 547 ok bool 548 temp int 549 uniqueSet = make(map[int]struct{}) 550 uniqueArray = make([]int, 0, len(a.array)) 551 ) 552 for i := 0; i < len(a.array); i++ { 553 temp = a.array[i] 554 if _, ok = uniqueSet[temp]; ok { 555 continue 556 } 557 uniqueSet[temp] = struct{}{} 558 uniqueArray = append(uniqueArray, temp) 559 } 560 a.array = uniqueArray 561 return a 562 } 563 564 // LockFunc locks writing by callback function `f`. 565 func (a *IntArray) LockFunc(f func(array []int)) *IntArray { 566 a.mu.Lock() 567 defer a.mu.Unlock() 568 f(a.array) 569 return a 570 } 571 572 // RLockFunc locks reading by callback function `f`. 573 func (a *IntArray) RLockFunc(f func(array []int)) *IntArray { 574 a.mu.RLock() 575 defer a.mu.RUnlock() 576 f(a.array) 577 return a 578 } 579 580 // Merge merges `array` into current array. 581 // The parameter `array` can be any garray or slice type. 582 // The difference between Merge and Append is Append supports only specified slice type, 583 // but Merge supports more parameter types. 584 func (a *IntArray) Merge(array interface{}) *IntArray { 585 return a.Append(gconv.Ints(array)...) 586 } 587 588 // Fill fills an array with num entries of the value `value`, 589 // keys starting at the `startIndex` parameter. 590 func (a *IntArray) Fill(startIndex int, num int, value int) error { 591 a.mu.Lock() 592 defer a.mu.Unlock() 593 if startIndex < 0 || startIndex > len(a.array) { 594 return gerror.NewCodef( 595 gcode.CodeInvalidParameter, 596 "index %d out of array range %d", 597 startIndex, len(a.array), 598 ) 599 } 600 for i := startIndex; i < startIndex+num; i++ { 601 if i > len(a.array)-1 { 602 a.array = append(a.array, value) 603 } else { 604 a.array[i] = value 605 } 606 } 607 return nil 608 } 609 610 // Chunk splits an array into multiple arrays, 611 // the size of each array is determined by `size`. 612 // The last chunk may contain less than size elements. 613 func (a *IntArray) Chunk(size int) [][]int { 614 if size < 1 { 615 return nil 616 } 617 a.mu.RLock() 618 defer a.mu.RUnlock() 619 length := len(a.array) 620 chunks := int(math.Ceil(float64(length) / float64(size))) 621 var n [][]int 622 for i, end := 0, 0; chunks > 0; chunks-- { 623 end = (i + 1) * size 624 if end > length { 625 end = length 626 } 627 n = append(n, a.array[i*size:end]) 628 i++ 629 } 630 return n 631 } 632 633 // Pad pads array to the specified length with `value`. 634 // If size is positive then the array is padded on the right, or negative on the left. 635 // If the absolute value of `size` is less than or equal to the length of the array 636 // then no padding takes place. 637 func (a *IntArray) Pad(size int, value int) *IntArray { 638 a.mu.Lock() 639 defer a.mu.Unlock() 640 if size == 0 || (size > 0 && size < len(a.array)) || (size < 0 && size > -len(a.array)) { 641 return a 642 } 643 n := size 644 if size < 0 { 645 n = -size 646 } 647 n -= len(a.array) 648 tmp := make([]int, n) 649 for i := 0; i < n; i++ { 650 tmp[i] = value 651 } 652 if size > 0 { 653 a.array = append(a.array, tmp...) 654 } else { 655 a.array = append(tmp, a.array...) 656 } 657 return a 658 } 659 660 // Rand randomly returns one item from array(no deleting). 661 func (a *IntArray) Rand() (value int, found bool) { 662 a.mu.RLock() 663 defer a.mu.RUnlock() 664 if len(a.array) == 0 { 665 return 0, false 666 } 667 return a.array[grand.Intn(len(a.array))], true 668 } 669 670 // Rands randomly returns `size` items from array(no deleting). 671 func (a *IntArray) Rands(size int) []int { 672 a.mu.RLock() 673 defer a.mu.RUnlock() 674 if size <= 0 || len(a.array) == 0 { 675 return nil 676 } 677 array := make([]int, size) 678 for i := 0; i < size; i++ { 679 array[i] = a.array[grand.Intn(len(a.array))] 680 } 681 return array 682 } 683 684 // Shuffle randomly shuffles the array. 685 func (a *IntArray) Shuffle() *IntArray { 686 a.mu.Lock() 687 defer a.mu.Unlock() 688 for i, v := range grand.Perm(len(a.array)) { 689 a.array[i], a.array[v] = a.array[v], a.array[i] 690 } 691 return a 692 } 693 694 // Reverse makes array with elements in reverse order. 695 func (a *IntArray) Reverse() *IntArray { 696 a.mu.Lock() 697 defer a.mu.Unlock() 698 for i, j := 0, len(a.array)-1; i < j; i, j = i+1, j-1 { 699 a.array[i], a.array[j] = a.array[j], a.array[i] 700 } 701 return a 702 } 703 704 // Join joins array elements with a string `glue`. 705 func (a *IntArray) Join(glue string) string { 706 a.mu.RLock() 707 defer a.mu.RUnlock() 708 if len(a.array) == 0 { 709 return "" 710 } 711 buffer := bytes.NewBuffer(nil) 712 for k, v := range a.array { 713 buffer.WriteString(gconv.String(v)) 714 if k != len(a.array)-1 { 715 buffer.WriteString(glue) 716 } 717 } 718 return buffer.String() 719 } 720 721 // CountValues counts the number of occurrences of all values in the array. 722 func (a *IntArray) CountValues() map[int]int { 723 m := make(map[int]int) 724 a.mu.RLock() 725 defer a.mu.RUnlock() 726 for _, v := range a.array { 727 m[v]++ 728 } 729 return m 730 } 731 732 // Iterator is alias of IteratorAsc. 733 func (a *IntArray) Iterator(f func(k int, v int) bool) { 734 a.IteratorAsc(f) 735 } 736 737 // IteratorAsc iterates the array readonly in ascending order with given callback function `f`. 738 // If `f` returns true, then it continues iterating; or false to stop. 739 func (a *IntArray) IteratorAsc(f func(k int, v int) bool) { 740 a.mu.RLock() 741 defer a.mu.RUnlock() 742 for k, v := range a.array { 743 if !f(k, v) { 744 break 745 } 746 } 747 } 748 749 // IteratorDesc iterates the array readonly in descending order with given callback function `f`. 750 // If `f` returns true, then it continues iterating; or false to stop. 751 func (a *IntArray) IteratorDesc(f func(k int, v int) bool) { 752 a.mu.RLock() 753 defer a.mu.RUnlock() 754 for i := len(a.array) - 1; i >= 0; i-- { 755 if !f(i, a.array[i]) { 756 break 757 } 758 } 759 } 760 761 // String returns current array as a string, which implements like json.Marshal does. 762 func (a *IntArray) String() string { 763 if a == nil { 764 return "" 765 } 766 return "[" + a.Join(",") + "]" 767 } 768 769 // MarshalJSON implements the interface MarshalJSON for json.Marshal. 770 // Note that do not use pointer as its receiver here. 771 func (a IntArray) MarshalJSON() ([]byte, error) { 772 a.mu.RLock() 773 defer a.mu.RUnlock() 774 return json.Marshal(a.array) 775 } 776 777 // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal. 778 func (a *IntArray) UnmarshalJSON(b []byte) error { 779 if a.array == nil { 780 a.array = make([]int, 0) 781 } 782 a.mu.Lock() 783 defer a.mu.Unlock() 784 if err := json.UnmarshalUseNumber(b, &a.array); err != nil { 785 return err 786 } 787 return nil 788 } 789 790 // UnmarshalValue is an interface implement which sets any type of value for array. 791 func (a *IntArray) UnmarshalValue(value interface{}) error { 792 a.mu.Lock() 793 defer a.mu.Unlock() 794 switch value.(type) { 795 case string, []byte: 796 return json.UnmarshalUseNumber(gconv.Bytes(value), &a.array) 797 default: 798 a.array = gconv.SliceInt(value) 799 } 800 return nil 801 } 802 803 // Filter iterates array and filters elements using custom callback function. 804 // It removes the element from array if callback function `filter` returns true, 805 // it or else does nothing and continues iterating. 806 func (a *IntArray) Filter(filter func(index int, value int) bool) *IntArray { 807 a.mu.Lock() 808 defer a.mu.Unlock() 809 for i := 0; i < len(a.array); { 810 if filter(i, a.array[i]) { 811 a.array = append(a.array[:i], a.array[i+1:]...) 812 } else { 813 i++ 814 } 815 } 816 return a 817 } 818 819 // FilterEmpty removes all zero value of the array. 820 func (a *IntArray) FilterEmpty() *IntArray { 821 a.mu.Lock() 822 defer a.mu.Unlock() 823 for i := 0; i < len(a.array); { 824 if a.array[i] == 0 { 825 a.array = append(a.array[:i], a.array[i+1:]...) 826 } else { 827 i++ 828 } 829 } 830 return a 831 } 832 833 // Walk applies a user supplied function `f` to every item of array. 834 func (a *IntArray) Walk(f func(value int) int) *IntArray { 835 a.mu.Lock() 836 defer a.mu.Unlock() 837 for i, v := range a.array { 838 a.array[i] = f(v) 839 } 840 return a 841 } 842 843 // IsEmpty checks whether the array is empty. 844 func (a *IntArray) IsEmpty() bool { 845 return a.Len() == 0 846 } 847 848 // DeepCopy implements interface for deep copy of current type. 849 func (a *IntArray) DeepCopy() interface{} { 850 if a == nil { 851 return nil 852 } 853 a.mu.RLock() 854 defer a.mu.RUnlock() 855 newSlice := make([]int, len(a.array)) 856 copy(newSlice, a.array) 857 return NewIntArrayFrom(newSlice, a.mu.IsSafe()) 858 }