gitlab.com/evatix-go/core@v1.3.55/coredata/corestr/LinkedCollections.go (about) 1 package corestr 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 "sync" 8 9 "gitlab.com/evatix-go/core/constants" 10 "gitlab.com/evatix-go/core/coredata/corejson" 11 "gitlab.com/evatix-go/core/coreindexes" 12 "gitlab.com/evatix-go/core/errcore" 13 ) 14 15 type LinkedCollections struct { 16 head, tail *LinkedCollectionNode 17 length int 18 sync.Mutex 19 } 20 21 func (it *LinkedCollections) Tail() *LinkedCollectionNode { 22 return it.tail 23 } 24 25 func (it *LinkedCollections) Head() *LinkedCollectionNode { 26 return it.head 27 } 28 29 func (it *LinkedCollections) First() *Collection { 30 return it.head.Element 31 } 32 33 func (it *LinkedCollections) Single() *Collection { 34 return it.head.Element 35 } 36 37 func (it *LinkedCollections) Last() *Collection { 38 return it.tail.Element 39 } 40 41 func (it *LinkedCollections) LastOrDefault() *Collection { 42 if it.IsEmpty() { 43 return Empty.Collection() 44 } 45 46 return it.tail.Element 47 } 48 49 func (it *LinkedCollections) FirstOrDefault() *Collection { 50 if it.IsEmpty() { 51 return Empty.Collection() 52 } 53 54 return it.head.Element 55 } 56 57 func (it *LinkedCollections) Length() int { 58 return it.length 59 } 60 61 // AllIndividualItemsLength including all nested ones 62 func (it *LinkedCollections) AllIndividualItemsLength() int { 63 allLengthSum := 0 64 65 var processor LinkedCollectionSimpleProcessor = func( 66 arg *LinkedCollectionProcessorParameter, 67 ) (isBreak bool) { 68 allLengthSum += arg.CurrentNode.Element.Length() 69 70 return false 71 } 72 73 it.Loop(processor) 74 75 return allLengthSum 76 } 77 78 func (it *LinkedCollections) incrementLength() int { 79 it.length++ 80 81 return it.length 82 } 83 84 func (it *LinkedCollections) setLengthToZero() int { 85 it.length = 0 86 87 return it.length 88 } 89 90 func (it *LinkedCollections) setLength(number int) int { 91 it.length = number 92 93 return it.length 94 } 95 96 func (it *LinkedCollections) decrementLength() int { 97 it.length-- 98 99 return it.length 100 } 101 102 func (it *LinkedCollections) incrementLengthLock() { 103 it.Lock() 104 it.length++ 105 it.Unlock() 106 } 107 108 func (it *LinkedCollections) incrementLengthUsingNumber(number int) int { 109 it.length += number 110 111 return it.length 112 } 113 114 func (it *LinkedCollections) LengthLock() int { 115 it.Lock() 116 defer it.Unlock() 117 118 return it.length 119 } 120 121 func (it *LinkedCollections) IsEqualsPtr( 122 anotherLinkedCollections *LinkedCollections, 123 ) bool { 124 if anotherLinkedCollections == nil { 125 return false 126 } 127 128 if it == anotherLinkedCollections { 129 return true 130 } 131 132 if it.IsEmpty() && anotherLinkedCollections.IsEmpty() { 133 return true 134 } 135 136 if it.IsEmpty() || anotherLinkedCollections.IsEmpty() { 137 return false 138 } 139 140 if it.Length() != anotherLinkedCollections.Length() { 141 return false 142 } 143 144 leftNode := it.head 145 rightNode := anotherLinkedCollections.head 146 147 if leftNode == nil && rightNode == nil { 148 return true 149 } 150 151 if leftNode == nil || rightNode == nil { 152 return false 153 } 154 155 return leftNode.IsChainEqual(rightNode) 156 } 157 158 func (it *LinkedCollections) IsEmptyLock() bool { 159 it.Lock() 160 defer it.Unlock() 161 162 return it.head == nil || it.length == 0 163 } 164 165 func (it *LinkedCollections) IsEmpty() bool { 166 return it.head == nil || it.length == 0 167 } 168 169 func (it *LinkedCollections) HasItems() bool { 170 return it.head != nil && 171 it.length > 0 172 } 173 174 // InsertAt BigO(n) expensive operation. 175 func (it *LinkedCollections) InsertAt( 176 index int, 177 collection *Collection, 178 ) *LinkedCollections { 179 if index < 1 { 180 return it.AddFront(collection) 181 } 182 183 node := it.IndexAt(index - 1) 184 it.AddAfterNode(node, collection) 185 186 return it 187 } 188 189 func (it *LinkedCollections) AddAsync( 190 collection *Collection, 191 wg *sync.WaitGroup, 192 ) *LinkedCollections { 193 go func() { 194 it.Lock() 195 defer it.Unlock() 196 it.Add(collection) 197 198 wg.Done() 199 }() 200 201 return it 202 } 203 204 // AddsAsyncOnComplete Append back 205 func (it *LinkedCollections) AddsAsyncOnComplete( 206 onComplete OnCompleteLinkedCollections, 207 isSkipOnNil bool, 208 collections ...*Collection, 209 ) *LinkedCollections { 210 go func() { 211 it.Lock() 212 defer it.Unlock() 213 214 it.AppendCollectionsPointers(isSkipOnNil, &collections) 215 216 onComplete(it) 217 }() 218 219 return it 220 } 221 222 // AddsUsingProcessorAsyncOnComplete Append back 223 func (it *LinkedCollections) AddsUsingProcessorAsyncOnComplete( 224 onComplete OnCompleteLinkedCollections, 225 processor AnyToCollectionProcessor, 226 isSkipOnNil bool, 227 anys ...interface{}, 228 ) *LinkedCollections { 229 go func() { 230 it.Lock() 231 defer it.Unlock() 232 233 if anys == nil && isSkipOnNil { 234 onComplete(it) 235 236 return 237 } 238 239 for i, any := range anys { 240 if any == nil && isSkipOnNil { 241 continue 242 } 243 244 collection := processor(any, i) 245 it.Add(collection) 246 } 247 248 onComplete(it) 249 }() 250 251 return it 252 } 253 254 // AddsUsingProcessorAsync Append back 255 func (it *LinkedCollections) AddsUsingProcessorAsync( 256 wg *sync.WaitGroup, 257 processor AnyToCollectionProcessor, 258 isSkipOnNil bool, 259 anys ...interface{}, 260 ) *LinkedCollections { 261 go func() { 262 it.Lock() 263 defer it.Unlock() 264 265 if anys == nil && isSkipOnNil { 266 wg.Done() 267 268 return 269 } 270 271 for i, any := range anys { 272 if any == nil && isSkipOnNil { 273 continue 274 } 275 276 collection := processor(any, i) 277 it.Add(collection) 278 } 279 280 wg.Done() 281 }() 282 283 return it 284 } 285 286 func (it *LinkedCollections) AddLock(collection *Collection) *LinkedCollections { 287 it.Lock() 288 defer it.Unlock() 289 290 return it.Add(collection) 291 } 292 293 func (it *LinkedCollections) Add(collection *Collection) *LinkedCollections { 294 if it.IsEmpty() { 295 it.head = &LinkedCollectionNode{ 296 Element: collection, 297 next: nil, 298 } 299 300 it.tail = it.head 301 it.incrementLength() 302 303 return it 304 } 305 306 it.tail.next = &LinkedCollectionNode{ 307 Element: collection, 308 next: nil, 309 } 310 311 it.tail = it.tail.next 312 it.incrementLength() 313 314 return it 315 } 316 317 func (it *LinkedCollections) AddStringsLock(stringsItems ...string) *LinkedCollections { 318 if len(stringsItems) == 0 { 319 return it 320 } 321 322 it.Lock() 323 defer it.Unlock() 324 325 return it.AddStringsPtr(false, &stringsItems) 326 } 327 328 func (it *LinkedCollections) AddStrings(stringsItems ...string) *LinkedCollections { 329 if len(stringsItems) == 0 { 330 return it 331 } 332 333 collection := New.Collection.StringsOptions(false, stringsItems) 334 335 return it.Add(collection) 336 } 337 338 func (it *LinkedCollections) AddBackNode(node *LinkedCollectionNode) *LinkedCollections { 339 return it.AppendNode(node) 340 } 341 342 func (it *LinkedCollections) AppendNode(node *LinkedCollectionNode) *LinkedCollections { 343 if it.IsEmpty() { 344 it.head = node 345 it.tail = it.head 346 it.incrementLength() 347 348 return it 349 } 350 351 it.tail.next = node 352 it.tail = it.tail.next 353 it.incrementLength() 354 355 return it 356 } 357 358 func (it *LinkedCollections) AppendChainOfNodes(nodeHead *LinkedCollectionNode) *LinkedCollections { 359 endOfChain, length := nodeHead.EndOfChain() 360 361 if it.IsEmpty() { 362 it.head = nodeHead 363 } else { 364 it.tail.next = nodeHead 365 } 366 367 it.tail = endOfChain 368 it.incrementLengthUsingNumber(length) 369 370 return it 371 } 372 373 func (it *LinkedCollections) AppendChainOfNodesAsync( 374 nodeHead *LinkedCollectionNode, 375 wg *sync.WaitGroup, 376 ) *LinkedCollections { 377 go func() { 378 it.Lock() 379 it.AppendChainOfNodes(nodeHead) 380 it.Unlock() 381 382 wg.Done() 383 }() 384 385 return it 386 } 387 388 func (it *LinkedCollections) PushBackLock(collection *Collection) *LinkedCollections { 389 return it.AddLock(collection) 390 } 391 392 func (it *LinkedCollections) PushBack(collection *Collection) *LinkedCollections { 393 return it.Add(collection) 394 } 395 396 func (it *LinkedCollections) Push(collection *Collection) *LinkedCollections { 397 return it.Add(collection) 398 } 399 400 func (it *LinkedCollections) PushFront(collection *Collection) *LinkedCollections { 401 return it.AddFront(collection) 402 } 403 404 func (it *LinkedCollections) AddFrontLock(collection *Collection) *LinkedCollections { 405 it.Lock() 406 defer it.Unlock() 407 408 return it.AddFront(collection) 409 } 410 411 func (it *LinkedCollections) AddFront(collection *Collection) *LinkedCollections { 412 if it.IsEmpty() { 413 return it.Add(collection) 414 } 415 416 node := &LinkedCollectionNode{ 417 Element: collection, 418 next: it.head, 419 } 420 421 it.head = node 422 it.incrementLength() 423 424 return it 425 } 426 427 func (it *LinkedCollections) AttachWithNode( 428 currentNode, 429 addingNode *LinkedCollectionNode, 430 ) error { 431 if currentNode == nil { 432 return errcore. 433 CannotBeNilType. 434 Error(currentNodeCannotBeNull, nil) 435 } 436 437 if currentNode.next != nil { 438 return errcore. 439 ShouldBeNilType. 440 Error("CurrentNode.next", nil) 441 } 442 443 addingNode.next = currentNode.next 444 currentNode.next = addingNode 445 it.incrementLength() 446 447 return nil 448 } 449 450 func (it *LinkedCollections) AddAnother( 451 another *LinkedCollections, 452 ) *LinkedCollections { 453 if another == nil || another.IsEmpty() { 454 return it 455 } 456 457 node := another.Head() 458 it.Add(node.Element) 459 460 for node.HasNext() { 461 node = node.Next() 462 463 it.Add(node.Element) 464 } 465 466 return it 467 } 468 469 // AddCollectionToNode iSkipOnNil 470 func (it *LinkedCollections) AddCollectionToNode( 471 isSkipOnNull bool, 472 node *LinkedCollectionNode, 473 collection *Collection, 474 ) *LinkedCollections { 475 return it.AddCollectionsToNode( 476 isSkipOnNull, 477 node, 478 collection) 479 } 480 481 func (it *LinkedCollections) GetNextNodes(count int) *[]*LinkedCollectionNode { 482 counter := 0 483 484 return it.Filter( 485 func( 486 arg *LinkedCollectionFilterParameter, 487 ) *LinkedCollectionFilterResult { 488 isBreak := counter >= count-1 489 490 counter++ 491 return &LinkedCollectionFilterResult{ 492 Value: arg.Node, 493 IsKeep: true, 494 IsBreak: isBreak, 495 } 496 }) 497 } 498 499 func (it *LinkedCollections) GetAllLinkedNodes() *[]*LinkedCollectionNode { 500 return it.Filter( 501 func( 502 arg *LinkedCollectionFilterParameter, 503 ) *LinkedCollectionFilterResult { 504 return &LinkedCollectionFilterResult{ 505 Value: arg.Node, 506 IsKeep: true, 507 IsBreak: false, 508 } 509 }) 510 } 511 512 func (it *LinkedCollections) Loop( 513 simpleProcessor LinkedCollectionSimpleProcessor, 514 ) *LinkedCollections { 515 length := it.Length() 516 if length == 0 { 517 return it 518 } 519 520 node := it.head 521 arg := &LinkedCollectionProcessorParameter{ 522 Index: 0, 523 CurrentNode: node, 524 PrevNode: nil, 525 IsFirstIndex: true, 526 IsEndingIndex: false, 527 } 528 529 isBreak := simpleProcessor(arg) 530 531 if isBreak { 532 return it 533 } 534 535 lenMinusOne := length - 1 536 index := 1 537 isEndingIndex := false 538 539 for node.HasNext() { 540 prev := node 541 node = node.Next() 542 isEndingIndex = lenMinusOne == index 543 544 arg2 := &LinkedCollectionProcessorParameter{ 545 Index: index, 546 CurrentNode: node, 547 PrevNode: prev, 548 IsFirstIndex: false, 549 IsEndingIndex: isEndingIndex, 550 } 551 552 isBreak = simpleProcessor(arg2) 553 554 if isBreak { 555 return it 556 } 557 558 index++ 559 } 560 561 return it 562 } 563 564 func (it *LinkedCollections) Filter( 565 filter LinkedCollectionFilter, 566 ) *[]*LinkedCollectionNode { 567 length := it.Length() 568 list := make([]*LinkedCollectionNode, 0, length) 569 570 if length == 0 { 571 return &list 572 } 573 574 node := it.head 575 arg := &LinkedCollectionFilterParameter{ 576 Node: node, 577 Index: 0, 578 } 579 580 result := filter(arg) 581 582 if result.IsKeep { 583 list = append(list, result.Value) 584 } 585 586 if result.IsBreak { 587 return &list 588 } 589 590 index := 1 591 for node.HasNext() { 592 node = node.Next() 593 594 arg2 := &LinkedCollectionFilterParameter{ 595 Node: node, 596 Index: index, 597 } 598 599 result2 := filter(arg2) 600 601 if result2.IsKeep { 602 list = append(list, result2.Value) 603 } 604 605 if result2.IsBreak { 606 return &list 607 } 608 609 index++ 610 } 611 612 return &list 613 } 614 615 func (it *LinkedCollections) FilterAsCollection( 616 filter LinkedCollectionFilter, 617 additionalCapacity int, 618 ) *Collection { 619 items := it.Filter(filter) 620 621 if len(*items) == 0 { 622 return New.Collection.Empty() 623 } 624 625 allLength := 0 626 627 for _, node := range *items { 628 if node != nil && node.Element != nil { 629 allLength += node.Element.Length() 630 } 631 } 632 633 collection := New.Collection.Cap(allLength + additionalCapacity) 634 635 for _, node := range *items { 636 if node == nil || node.Element == nil { 637 continue 638 } 639 640 collection.AddCollection(node.Element) 641 } 642 643 return collection 644 } 645 646 func (it *LinkedCollections) FilterAsCollections( 647 filter LinkedCollectionFilter, 648 ) *[]*Collection { 649 items := it.Filter(filter) 650 collections := make([]*Collection, len(*items)) 651 652 for i := range *items { 653 collections[i] = (*items)[i].Element 654 } 655 656 return &collections 657 } 658 659 func (it *LinkedCollections) RemoveNodeByIndex( 660 removingIndex int, 661 ) *LinkedCollections { 662 if removingIndex < 0 { 663 errcore. 664 CannotBeNegativeIndexType. 665 HandleUsingPanic( 666 "removeIndex was less than 0.", 667 removingIndex) 668 } 669 670 var singleProcessor LinkedCollectionSimpleProcessor = func( 671 arg *LinkedCollectionProcessorParameter, 672 ) (isBreak bool) { 673 hasIndex := removingIndex == arg.Index 674 675 if !hasIndex { 676 return false 677 } 678 679 isBreak = hasIndex 680 it.decrementLength() 681 682 if arg.IsFirstIndex { 683 it.head = 684 arg.CurrentNode.next 685 arg.CurrentNode = nil 686 return isBreak 687 } 688 689 if arg.IsEndingIndex { 690 arg.PrevNode.next = nil 691 arg.CurrentNode = nil 692 693 return isBreak 694 } 695 696 arg.PrevNode.next = arg.CurrentNode.next 697 arg.CurrentNode = nil 698 699 return isBreak 700 } 701 702 return it.Loop(singleProcessor) 703 } 704 705 func (it *LinkedCollections) RemoveNodeByIndexes( 706 isIgnorePanic bool, 707 removingIndexes ...int, 708 ) *LinkedCollections { 709 length := len(removingIndexes) 710 711 if length == 0 { 712 return it 713 } 714 715 if !isIgnorePanic && it.IsEmpty() && length > 0 { 716 errcore. 717 CannotRemoveIndexesFromEmptyCollectionType. 718 HandleUsingPanic("removingIndexes cannot be removed from Empty LinkedCollections.", removingIndexes) 719 } 720 721 nonChainedNodes := it.Filter( 722 func(arg *LinkedCollectionFilterParameter) *LinkedCollectionFilterResult { 723 hasIndex := coreindexes.HasIndexPlusRemoveIndex(removingIndexes, arg.Index) 724 if hasIndex { 725 // remove 726 return &LinkedCollectionFilterResult{ 727 Value: arg.Node, 728 IsKeep: false, 729 IsBreak: false, 730 } 731 } 732 733 // not remove 734 return &LinkedCollectionFilterResult{ 735 Value: arg.Node, 736 IsKeep: true, 737 IsBreak: false, 738 } 739 }) 740 741 nonChainedCollection := &NonChainedLinkedCollectionNodes{ 742 items: nonChainedNodes, 743 isChainingApplied: false, 744 } 745 746 if nonChainedCollection.IsEmpty() { 747 return it 748 } 749 750 it.setLength(nonChainedCollection.Length()) 751 it.head = nonChainedCollection.ApplyChaining().First() 752 753 return it 754 } 755 756 func (it *LinkedCollections) RemoveNode( 757 removingNode *LinkedCollectionNode, 758 ) *LinkedCollections { 759 var processor LinkedCollectionSimpleProcessor = func( 760 arg *LinkedCollectionProcessorParameter, 761 ) (isBreak bool) { 762 isSameNode := arg.CurrentNode == removingNode 763 if isSameNode && arg.IsFirstIndex { 764 it.head = arg.CurrentNode.next 765 it.decrementLength() 766 767 return true 768 } 769 770 if isSameNode { 771 arg.PrevNode.next = arg.CurrentNode.next 772 it.decrementLength() 773 774 return true 775 } 776 777 return false 778 } 779 780 return it.Loop(processor) 781 } 782 783 // AppendCollections iSkipOnNil 784 func (it *LinkedCollections) AppendCollections( 785 isSkipOnNull bool, 786 collections ...*Collection, 787 ) *LinkedCollections { 788 if isSkipOnNull && collections == nil { 789 return it 790 } 791 792 for i := range collections { 793 collection := collections[i] 794 if isSkipOnNull && collection == nil { 795 continue 796 } 797 798 it.Add(collection) 799 } 800 801 return it 802 } 803 804 // AppendCollectionsPointersLock iSkipOnNil 805 func (it *LinkedCollections) AppendCollectionsPointersLock( 806 isSkipOnNull bool, 807 collections *[]*Collection, 808 ) *LinkedCollections { 809 if isSkipOnNull && collections == nil { 810 return it 811 } 812 813 for i := range *collections { 814 collection := (*collections)[i] 815 if isSkipOnNull && collection == nil { 816 continue 817 } 818 819 it.AddLock(collection) 820 } 821 822 return it 823 } 824 825 // AppendCollectionsPointers iSkipOnNil 826 func (it *LinkedCollections) AppendCollectionsPointers( 827 isSkipOnNull bool, 828 collections *[]*Collection, 829 ) *LinkedCollections { 830 if isSkipOnNull && collections == nil { 831 return it 832 } 833 834 for i := range *collections { 835 collection := (*collections)[i] 836 if isSkipOnNull && collection == nil { 837 continue 838 } 839 840 it.Add(collection) 841 } 842 843 return it 844 } 845 846 // AddCollectionsToNodeAsync iSkipOnNil 847 func (it *LinkedCollections) AddCollectionsToNodeAsync( 848 isSkipOnNull bool, 849 wg *sync.WaitGroup, 850 node *LinkedCollectionNode, 851 collections ...*Collection, 852 ) *LinkedCollections { 853 if isSkipOnNull && collections == nil { 854 return it 855 } 856 857 go func() { 858 it.Lock() 859 it.AddCollectionsPointerToNode( 860 isSkipOnNull, 861 node, 862 &collections) 863 864 it.Unlock() 865 866 wg.Done() 867 }() 868 869 return it 870 } 871 872 // AddCollectionsToNode iSkipOnNil 873 func (it *LinkedCollections) AddCollectionsToNode( 874 isSkipOnNull bool, 875 node *LinkedCollectionNode, 876 collections ...*Collection, 877 ) *LinkedCollections { 878 if isSkipOnNull && collections == nil { 879 return it 880 } 881 882 return it.AddCollectionsPointerToNode( 883 isSkipOnNull, 884 node, 885 &collections) 886 } 887 888 // AddCollectionsPointerToNode iSkipOnNil 889 func (it *LinkedCollections) AddCollectionsPointerToNode( 890 isSkipOnNull bool, 891 node *LinkedCollectionNode, 892 items *[]*Collection, 893 ) *LinkedCollections { 894 if items == nil || node == nil && isSkipOnNull { 895 return it 896 } 897 898 if node == nil { 899 errcore. 900 CannotBeNilType. 901 HandleUsingPanic( 902 nodesCannotBeNull, 903 nil) 904 } 905 906 length := len(*items) 907 908 if length == 0 { 909 return it 910 } 911 912 if length == 1 { 913 it.AddAfterNode(node, (*items)[0]) 914 915 return it 916 } 917 918 finalHead := &LinkedCollectionNode{ 919 Element: (*items)[0], 920 next: nil, 921 } 922 923 nextNode := finalHead 924 925 for _, collection := range (*items)[1:] { 926 if isSkipOnNull && collection == nil { 927 continue 928 } 929 930 nextNode = nextNode.AddNext(it, collection) 931 } 932 933 //goland:noinspection GoNilness 934 nextNode.next = node.next 935 //goland:noinspection GoNilness 936 node.next = finalHead 937 it.incrementLength() 938 939 return it 940 } 941 942 func (it *LinkedCollections) AddAfterNode( 943 node *LinkedCollectionNode, 944 collection *Collection, 945 ) *LinkedCollectionNode { 946 newNode := &LinkedCollectionNode{ 947 Element: collection, 948 next: node.next, 949 } 950 951 node.next = newNode 952 it.incrementLength() 953 954 return newNode 955 } 956 957 func (it *LinkedCollections) AddAfterNodeAsync( 958 wg *sync.WaitGroup, 959 node *LinkedCollectionNode, 960 collection *Collection, 961 ) { 962 go func() { 963 it.Lock() 964 965 it.AddAfterNode(node, collection) 966 967 it.Unlock() 968 969 wg.Done() 970 }() 971 } 972 973 // AddStringsPtrAsync add to back 974 func (it *LinkedCollections) AddStringsPtrAsync( 975 wg *sync.WaitGroup, 976 isMakeClone bool, 977 items *[]string, 978 ) *LinkedCollections { 979 if items == nil { 980 return it 981 } 982 983 go func() { 984 collection := New.Collection.StringsPtrOption(isMakeClone, items) 985 986 it.Lock() 987 988 it.Add(collection) 989 990 it.Unlock() 991 992 wg.Done() 993 }() 994 995 return it 996 } 997 998 func (it *LinkedCollections) ConcatNew( 999 isMakeCloneOnEmpty bool, 1000 linkedCollectionsOfCollection ...*LinkedCollections, 1001 ) *LinkedCollections { 1002 isEmpty := len(linkedCollectionsOfCollection) == 0 1003 1004 if isEmpty && isMakeCloneOnEmpty { 1005 return New. 1006 LinkedCollection. 1007 Create(). 1008 AddAnother(it) 1009 } else if isEmpty && !isMakeCloneOnEmpty { 1010 return it 1011 } 1012 1013 newLinkedCollections := New. 1014 LinkedCollection. 1015 Create() 1016 newLinkedCollections.AddAnother(it) 1017 1018 for _, linkedCollection := range linkedCollectionsOfCollection { 1019 newLinkedCollections.AddAnother(linkedCollection) 1020 } 1021 1022 return newLinkedCollections 1023 } 1024 1025 // AddAsyncFuncItems must add all the lengths to the wg 1026 func (it *LinkedCollections) AddAsyncFuncItems( 1027 wg *sync.WaitGroup, 1028 isMakeClone bool, 1029 asyncFunctions ...func() []string, 1030 ) *LinkedCollections { 1031 if asyncFunctions == nil { 1032 return it 1033 } 1034 1035 asyncFuncWrap := func(asyncFunc func() []string) { 1036 items := asyncFunc() 1037 1038 if len(items) == 0 { 1039 wg.Done() 1040 1041 return 1042 } 1043 1044 collection := New.Collection.StringsOptions(isMakeClone, items) 1045 1046 it.Lock() 1047 it.Add(collection) 1048 it.Unlock() 1049 1050 wg.Done() 1051 } 1052 1053 for _, function := range asyncFunctions { 1054 go asyncFuncWrap(function) 1055 } 1056 1057 wg.Wait() 1058 1059 return it 1060 } 1061 1062 // AddAsyncFuncItemsPointer must add all the lengths to the wg 1063 func (it *LinkedCollections) AddAsyncFuncItemsPointer( 1064 wg *sync.WaitGroup, 1065 isMakeClone bool, 1066 asyncFunctions ...func() *[]string, 1067 ) *LinkedCollections { 1068 if asyncFunctions == nil { 1069 return it 1070 } 1071 1072 asyncFuncWrap := func(asyncFunc func() *[]string) { 1073 items := asyncFunc() 1074 1075 if items == nil || len(*items) == 0 { 1076 wg.Done() 1077 1078 return 1079 } 1080 1081 collection := New.Collection.StringsPtrOption(isMakeClone, items) 1082 1083 it.Lock() 1084 it.Add(collection) 1085 it.Unlock() 1086 1087 wg.Done() 1088 } 1089 1090 for _, function := range asyncFunctions { 1091 go asyncFuncWrap(function) 1092 } 1093 1094 wg.Wait() 1095 1096 return it 1097 } 1098 1099 // AddStringsPtr add to back 1100 func (it *LinkedCollections) AddStringsPtr( 1101 isMakeClone bool, 1102 items *[]string, 1103 ) *LinkedCollections { 1104 if items == nil { 1105 return it 1106 } 1107 1108 collection := New.Collection.StringsPtrOption(isMakeClone, items) 1109 1110 return it.Add(collection) 1111 } 1112 1113 // AddStringsOfStringsPtr add to back 1114 func (it *LinkedCollections) AddStringsOfStringsPtr( 1115 items *[]*[]string, 1116 isMakeClone bool, 1117 ) *LinkedCollections { 1118 if items == nil || len(*items) == 0 { 1119 return it 1120 } 1121 1122 for _, stringItems := range *items { 1123 if stringItems == nil { 1124 continue 1125 } 1126 1127 it.AddStringsPtr( 1128 isMakeClone, 1129 stringItems, 1130 ) 1131 } 1132 1133 return it 1134 } 1135 1136 // IndexAt Expensive operation BigO(n) 1137 func (it *LinkedCollections) IndexAt( 1138 index int, 1139 ) *LinkedCollectionNode { 1140 length := it.Length() 1141 if index < 0 { 1142 return nil 1143 } 1144 1145 if length == 0 || length-1 < index { 1146 errcore.OutOfRangeType.HandleUsingPanic( 1147 "Given index is out of range. Whereas length:", 1148 length) 1149 } 1150 1151 if index == 0 { 1152 return it.head 1153 } 1154 1155 node := it.head 1156 i := 1 1157 for node.HasNext() { 1158 node = node.Next() 1159 1160 if i == index { 1161 return node 1162 } 1163 1164 i++ 1165 } 1166 1167 return nil 1168 } 1169 1170 // SafePointerIndexAt Expensive operation BigO(n) 1171 func (it *LinkedCollections) SafePointerIndexAt( 1172 index int, 1173 ) *Collection { 1174 node := it.SafeIndexAt(index) 1175 1176 if node == nil { 1177 return nil 1178 } 1179 1180 return node.Element 1181 } 1182 1183 // SafeIndexAt Expensive operation BigO(n) 1184 func (it *LinkedCollections) SafeIndexAt( 1185 index int, 1186 ) *LinkedCollectionNode { 1187 length := it.Length() 1188 isExitCondition := index < 0 || length == 0 || length-1 < index 1189 if isExitCondition { 1190 return nil 1191 } 1192 1193 if index == 0 { 1194 return it.head 1195 } 1196 1197 node := it.head 1198 i := 1 1199 for node.HasNext() { 1200 node = node.Next() 1201 1202 if i == index { 1203 return node 1204 } 1205 1206 i++ 1207 } 1208 1209 return nil 1210 } 1211 1212 // AddPointerStringsPtr skip on nil, add to back 1213 func (it *LinkedCollections) AddPointerStringsPtr( 1214 items *[]*string, 1215 ) *LinkedCollections { 1216 if items == nil { 1217 return it 1218 } 1219 1220 collection := New.Collection.PointerStrings(*items) 1221 1222 return it.Add(collection) 1223 } 1224 1225 // AddPointerStringsPtrAsync skip on nil, add to back 1226 func (it *LinkedCollections) AddPointerStringsPtrAsync( 1227 wg *sync.WaitGroup, 1228 items *[]*string, 1229 ) *LinkedCollections { 1230 if items == nil { 1231 return it 1232 } 1233 1234 go func() { 1235 collection := New.Collection.PointerStrings(*items) 1236 1237 it.Lock() 1238 it.Add(collection) 1239 it.Unlock() 1240 1241 wg.Done() 1242 }() 1243 1244 return it 1245 } 1246 1247 // AddCollection skip on nil 1248 func (it *LinkedCollections) AddCollection( 1249 collection *Collection, 1250 ) *LinkedCollections { 1251 if collection == nil { 1252 return it 1253 } 1254 1255 return it.Add(collection) 1256 } 1257 1258 // AddCollectionsPtr skip on nil 1259 func (it *LinkedCollections) AddCollectionsPtr( 1260 collectionsOfCollection *[]*Collection, 1261 ) *LinkedCollections { 1262 if collectionsOfCollection == nil || len(*collectionsOfCollection) == 0 { 1263 return it 1264 } 1265 1266 return it.AddCollections(*collectionsOfCollection) 1267 } 1268 1269 // AddCollections skip on nil 1270 func (it *LinkedCollections) AddCollections( 1271 collectionsOfCollection []*Collection, 1272 ) *LinkedCollections { 1273 if len(collectionsOfCollection) == 0 { 1274 return it 1275 } 1276 1277 for _, collection := range collectionsOfCollection { 1278 if collection == nil { 1279 continue 1280 } 1281 1282 return it.Add(collection) 1283 } 1284 1285 return it 1286 } 1287 1288 func (it *LinkedCollections) ToStringsPtr() *[]string { 1289 return it.ToCollectionSimple().ListPtr() 1290 } 1291 1292 func (it *LinkedCollections) ToStrings() []string { 1293 return it.ToCollectionSimple().List() 1294 } 1295 1296 func (it *LinkedCollections) ToCollectionSimple() *Collection { 1297 return it.ToCollection(constants.Zero) 1298 } 1299 1300 func (it *LinkedCollections) ToCollection( 1301 addCapacity int, 1302 ) *Collection { 1303 if it.IsEmpty() { 1304 return New.Collection.Empty() 1305 } 1306 1307 newLength := it.AllIndividualItemsLength() + 1308 addCapacity 1309 1310 collection := New.Collection.Cap(newLength) 1311 var processor LinkedCollectionSimpleProcessor = func( 1312 arg *LinkedCollectionProcessorParameter, 1313 ) (isBreak bool) { 1314 if arg.CurrentNode == nil { 1315 return false 1316 } 1317 1318 collection.AddCollection(arg.CurrentNode.Element) 1319 1320 return false 1321 } 1322 1323 it.Loop(processor) 1324 1325 return collection 1326 } 1327 1328 func (it *LinkedCollections) ToCollectionsOfCollection( 1329 addCapacity int, 1330 ) *CollectionsOfCollection { 1331 if it.IsEmpty() { 1332 return Empty.CollectionsOfCollection() 1333 } 1334 1335 newLength := it.AllIndividualItemsLength() + 1336 addCapacity 1337 1338 collection := New.CollectionsOfCollection.Cap(newLength) 1339 1340 var processor LinkedCollectionSimpleProcessor = func( 1341 arg *LinkedCollectionProcessorParameter, 1342 ) (isBreak bool) { 1343 if arg.CurrentNode == nil { 1344 return false 1345 } 1346 1347 collection.Adds(arg.CurrentNode.Element) 1348 1349 return false 1350 } 1351 1352 it.Loop(processor) 1353 1354 return collection 1355 } 1356 1357 func (it *LinkedCollections) ItemsOfItems() *[]*[]string { 1358 length := it.Length() 1359 itemsOfItems := make([]*[]string, length) 1360 1361 if length == 0 { 1362 return &itemsOfItems 1363 } 1364 1365 nodes := it.GetAllLinkedNodes() 1366 1367 for i, node := range *nodes { 1368 itemsOfItems[i] = &node.Element.items 1369 } 1370 1371 return &itemsOfItems 1372 } 1373 1374 func (it *LinkedCollections) ItemsOfItemsCollection() *[]*Collection { 1375 length := it.Length() 1376 itemsOfItems := make([]*Collection, length) 1377 1378 if length == 0 { 1379 return &itemsOfItems 1380 } 1381 1382 nodes := it.GetAllLinkedNodes() 1383 1384 for i, node := range *nodes { 1385 itemsOfItems[i] = node.Element 1386 } 1387 1388 return &itemsOfItems 1389 } 1390 1391 // ListPtr must return slice. 1392 func (it *LinkedCollections) ListPtr() *[]string { 1393 return it. 1394 ToCollection(constants.ArbitraryCapacity5). 1395 ListPtr() 1396 } 1397 1398 func (it *LinkedCollections) String() string { 1399 if it.IsEmpty() { 1400 return commonJoiner + NoElements 1401 } 1402 1403 collections := *it.ToCollectionsOfCollection(0) 1404 1405 return collections.String() 1406 } 1407 1408 func (it *LinkedCollections) StringLock() string { 1409 if it.IsEmptyLock() { 1410 return commonJoiner + NoElements 1411 } 1412 1413 it.Lock() 1414 defer it.Unlock() 1415 1416 return commonJoiner + 1417 strings.Join( 1418 *it.ListPtr(), 1419 commonJoiner) 1420 } 1421 1422 func (it *LinkedCollections) Join( 1423 separator string, 1424 ) string { 1425 return strings.Join(*it.ListPtr(), separator) 1426 } 1427 1428 func (it *LinkedCollections) Joins( 1429 separator string, 1430 items ...string, 1431 ) string { 1432 if items == nil || it.Length() == 0 { 1433 return strings.Join(items, separator) 1434 } 1435 1436 collection := it.ToCollection(len(items) + 1437 constants.ArbitraryCapacity2) 1438 collection.AddStringsPtr(&items) 1439 1440 return collection.Join(separator) 1441 } 1442 1443 func (it *LinkedCollections) JsonModel() []string { 1444 return it.ToCollection(0).JsonModel() 1445 } 1446 1447 func (it *LinkedCollections) JsonModelAny() interface{} { 1448 return it.JsonModel() 1449 } 1450 1451 func (it *LinkedCollections) MarshalJSON() ([]byte, error) { 1452 return json.Marshal(it.JsonModel()) 1453 } 1454 1455 func (it *LinkedCollections) UnmarshalJSON(data []byte) error { 1456 var dataModelStrings []string 1457 err := json.Unmarshal(data, &dataModelStrings) 1458 1459 if err == nil { 1460 it.Clear() 1461 it.AddStrings(dataModelStrings...) 1462 } 1463 1464 return err 1465 } 1466 1467 func (it *LinkedCollections) RemoveAll() *LinkedCollections { 1468 return it.Clear() 1469 } 1470 1471 func (it *LinkedCollections) Clear() *LinkedCollections { 1472 if it.IsEmpty() { 1473 return it 1474 } 1475 1476 it.head = nil 1477 it.tail = nil 1478 it.setLengthToZero() 1479 1480 return it 1481 } 1482 1483 func (it LinkedCollections) Json() corejson.Result { 1484 return corejson.New(it) 1485 } 1486 1487 func (it LinkedCollections) JsonPtr() *corejson.Result { 1488 return corejson.NewPtr(it) 1489 } 1490 1491 func (it *LinkedCollections) ParseInjectUsingJson( 1492 jsonResult *corejson.Result, 1493 ) (*LinkedCollections, error) { 1494 err := jsonResult.Unmarshal(it) 1495 1496 if err != nil { 1497 return nil, err 1498 } 1499 1500 return it, nil 1501 } 1502 1503 // ParseInjectUsingJsonMust Panic if error 1504 func (it *LinkedCollections) ParseInjectUsingJsonMust( 1505 jsonResult *corejson.Result, 1506 ) *LinkedCollections { 1507 newUsingJson, err := 1508 it.ParseInjectUsingJson(jsonResult) 1509 1510 if err != nil { 1511 panic(err) 1512 } 1513 1514 return newUsingJson 1515 } 1516 1517 func (it *LinkedCollections) GetCompareSummary( 1518 right *LinkedCollections, leftName, rightName string, 1519 ) string { 1520 lLen := it.Length() 1521 rLen := right.Length() 1522 1523 leftStr := fmt.Sprintf( 1524 linkedListCollectionCompareHeaderLeft, 1525 leftName, 1526 lLen, 1527 it) 1528 1529 rightStr := fmt.Sprintf( 1530 linkedListCollectionCompareHeaderRight, 1531 rightName, 1532 rLen, 1533 right, 1534 it.IsEqualsPtr(right), 1535 lLen, 1536 rLen) 1537 1538 return leftStr + rightStr 1539 } 1540 1541 func (it *LinkedCollections) JsonParseSelfInject( 1542 jsonResult *corejson.Result, 1543 ) error { 1544 _, err := it.ParseInjectUsingJson( 1545 jsonResult, 1546 ) 1547 1548 return err 1549 } 1550 1551 func (it *LinkedCollections) AsJsonContractsBinder() corejson.JsonContractsBinder { 1552 return it 1553 } 1554 1555 func (it *LinkedCollections) AsJsoner() corejson.Jsoner { 1556 return it 1557 } 1558 1559 func (it *LinkedCollections) AsJsonParseSelfInjector() corejson.JsonParseSelfInjector { 1560 return it 1561 } 1562 1563 func (it *LinkedCollections) AsJsonMarshaller() corejson.JsonMarshaller { 1564 return it 1565 }