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