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