gitlab.com/evatix-go/core@v1.3.55/coredata/corestr/Hashset.go (about) 1 package corestr 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "sort" 7 "strings" 8 "sync" 9 10 "gitlab.com/evatix-go/core/constants" 11 "gitlab.com/evatix-go/core/converters" 12 "gitlab.com/evatix-go/core/coredata/corejson" 13 "gitlab.com/evatix-go/core/coredata/stringslice" 14 "gitlab.com/evatix-go/core/internal/mapdiffinternal" 15 "gitlab.com/evatix-go/core/internal/strutilinternal" 16 ) 17 18 type Hashset struct { 19 hasMapUpdated bool 20 isEmptySet bool 21 length int 22 items map[string]bool 23 cachedList []string 24 sync.Mutex 25 } 26 27 func (it *Hashset) IsEmpty() bool { 28 if it == nil { 29 return true 30 } 31 32 if it.hasMapUpdated { 33 it.isEmptySet = len(it.items) == 0 34 } 35 36 return it.isEmptySet 37 } 38 39 func (it *Hashset) HasItems() bool { 40 return !it.IsEmpty() 41 } 42 43 // AddCapacitiesLock Changing capacity creates new map and points to it. 44 // There is memory copy and loop is performed. 45 func (it *Hashset) AddCapacitiesLock( 46 capacities ...int, 47 ) *Hashset { 48 length := it.LengthLock() 49 50 if len(capacities) == 0 { 51 return it 52 } 53 54 for _, capacity := range capacities { 55 length += capacity 56 } 57 58 return it.ResizeLock(length) 59 } 60 61 // AddCapacities Changing capacity creates new map and points to it. 62 // There is memory copy and loop is performed. 63 func (it *Hashset) AddCapacities( 64 capacities ...int, 65 ) *Hashset { 66 length := it.Length() 67 68 if len(capacities) == 0 { 69 return it 70 } 71 72 for _, capacity := range capacities { 73 length += capacity 74 } 75 76 return it.Resize(length) 77 } 78 79 // Resize Changing capacity creates new map and points to it. 80 // There is memory copy and loop is performed. 81 func (it *Hashset) Resize(capacity int) *Hashset { 82 length := it.Length() 83 84 if length > capacity { 85 return it 86 } 87 88 newItemsMap := make(map[string]bool, capacity) 89 90 for val := range it.items { 91 newItemsMap[val] = true 92 } 93 94 it.items = newItemsMap 95 96 return it 97 } 98 99 // ResizeLock Changing capacity creates new map and points to it. 100 // There is memory copy and loop is performed. 101 func (it *Hashset) ResizeLock(capacity int) *Hashset { 102 length := it.LengthLock() 103 104 if length > capacity { 105 return it 106 } 107 108 newItemsMap := make(map[string]bool, capacity) 109 110 for val := range it.items { 111 newItemsMap[val] = true 112 } 113 114 it.Lock() 115 it.items = newItemsMap 116 it.Unlock() 117 118 return it 119 } 120 121 func (it *Hashset) Collection() *Collection { 122 return New.Collection.StringsOptions(false, it.List()) 123 } 124 125 func (it *Hashset) IsEmptyLock() bool { 126 it.Lock() 127 defer it.Unlock() 128 129 return it.IsEmpty() 130 } 131 132 func (it *Hashset) ConcatNewHashsets( 133 isCloneCurrentOnEmpty bool, 134 hashsets ...*Hashset, 135 ) *Hashset { 136 isEmpty := hashsets == nil || len(hashsets) == 0 137 138 if isEmpty { 139 return New.Hashset.UsingMapOption( 140 constants.Zero, 141 isCloneCurrentOnEmpty, 142 it.items, 143 ) 144 } 145 146 length := it.Length() + constants.Capacity4 147 148 for _, h := range hashsets { 149 if h == nil { 150 continue 151 } 152 153 length += h.Length() 154 } 155 156 newHashset := New.Hashset.UsingMapOption( 157 length, 158 isCloneCurrentOnEmpty, 159 it.items, 160 ) 161 162 newHashset.AddHashsetItems(it) 163 164 for _, h := range hashsets { 165 newHashset.AddHashsetItems(h) 166 } 167 168 return newHashset 169 } 170 171 func (it *Hashset) ConcatNewStringsPointers( 172 isCloneCurrentOnEmpty bool, 173 stringsOfStringsItems ...*[]string, 174 ) *Hashset { 175 isEmpty := len(stringsOfStringsItems) == 0 176 177 if isEmpty { 178 return New.Hashset.UsingMapOption( 179 constants.Zero, 180 isCloneCurrentOnEmpty, 181 it.items, 182 ) 183 } 184 185 length := AllIndividualItemsStringsOfStringsPointerLength(&stringsOfStringsItems) + 186 it.Length() + 187 constants.Capacity4 188 189 newHashset := New.Hashset.UsingMapOption( 190 length, 191 isCloneCurrentOnEmpty, 192 it.items, 193 ) 194 195 newHashset.AddHashsetItems(it) 196 197 for _, stringsItems := range stringsOfStringsItems { 198 newHashset.AddStringsPtr(stringsItems) 199 } 200 201 return newHashset 202 } 203 204 func (it *Hashset) ConcatNewStrings( 205 isCloneCurrentOnEmpty bool, 206 stringsOfStringsItems ...[]string, 207 ) *Hashset { 208 isEmpty := len(stringsOfStringsItems) == 0 209 210 if isEmpty { 211 return New.Hashset.UsingMapOption( 212 constants.Zero, 213 isCloneCurrentOnEmpty, 214 it.items, 215 ) 216 } 217 218 length := AllIndividualStringsOfStringsLength(&stringsOfStringsItems) + 219 it.Length() + 220 constants.Capacity4 221 newHashset := New.Hashset.UsingMapOption( 222 length, 223 true, 224 it.items, 225 ) 226 227 newHashset.AddHashsetItems(it) 228 229 for _, stringsItems := range stringsOfStringsItems { 230 newHashset.AddStrings(stringsItems) 231 } 232 233 return newHashset 234 } 235 236 func (it *Hashset) AddPtr(key *string) *Hashset { 237 it.items[*key] = true 238 it.hasMapUpdated = true 239 240 return it 241 } 242 243 func (it *Hashset) AddWithWgLock( 244 key string, 245 group *sync.WaitGroup, 246 ) *Hashset { 247 it.Lock() 248 it.items[key] = true 249 it.Unlock() 250 251 it.hasMapUpdated = true 252 253 group.Done() 254 255 return it 256 } 257 258 func (it *Hashset) AddPtrLock(key *string) *Hashset { 259 it.Lock() 260 it.items[*key] = true 261 it.Unlock() 262 263 it.hasMapUpdated = true 264 265 return it 266 } 267 268 func (it *Hashset) Add(key string) *Hashset { 269 it.items[key] = true 270 it.hasMapUpdated = true 271 272 return it 273 } 274 275 func (it *Hashset) AddBool(key string) (isExist bool) { 276 _, has := it.items[key] 277 278 if !has { 279 it.items[key] = true 280 } 281 282 return has 283 } 284 285 func (it *Hashset) AddNonEmpty(str string) *Hashset { 286 if str == "" { 287 return it 288 } 289 290 return it 291 } 292 293 func (it *Hashset) AddNonEmptyWhitespace(str string) *Hashset { 294 if strutilinternal.IsEmptyOrWhitespace(str) { 295 return it 296 } 297 298 return it.Add(str) 299 } 300 301 func (it *Hashset) AddIf(isAdd bool, addingString string) *Hashset { 302 if !isAdd { 303 return it 304 } 305 306 return it.Add(addingString) 307 } 308 309 func (it *Hashset) AddIfMany( 310 isAdd bool, 311 addingStrings ...string, 312 ) *Hashset { 313 if !isAdd { 314 return it 315 } 316 317 return it.Adds(addingStrings...) 318 } 319 320 func (it *Hashset) AddFunc(f func() string) *Hashset { 321 return it.Add(f()) 322 } 323 324 func (it *Hashset) AddFuncErr( 325 funcReturnsError func() (result string, err error), 326 errHandler func(errInput error), 327 ) *Hashset { 328 r, err := funcReturnsError() 329 330 if err != nil { 331 errHandler(err) 332 333 return it 334 } 335 336 return it.Add(r) 337 } 338 339 func (it *Hashset) AddStringsPtrWgLock( 340 keys *[]string, wg *sync.WaitGroup, 341 ) *Hashset { 342 if keys == nil { 343 return it 344 } 345 346 length := len(*keys) 347 348 if length > it.length || length > constants.ArbitraryCapacity100 { 349 it.AddCapacitiesLock(length*2, constants.ArbitraryCapacity100) 350 } 351 352 it.Lock() 353 for _, key := range *keys { 354 it.items[key] = true 355 } 356 357 it.Unlock() 358 wg.Done() 359 360 it.hasMapUpdated = true 361 362 return it 363 } 364 365 func (it *Hashset) AddHashsetItems( 366 hashsetAdd *Hashset, 367 ) *Hashset { 368 if hashsetAdd == nil { 369 return it 370 } 371 372 length := hashsetAdd.Length() 373 374 if length > it.length || length > constants.ArbitraryCapacity100 { 375 it.AddCapacities(length*2, constants.ArbitraryCapacity100) 376 } 377 378 for k := range hashsetAdd.items { 379 it.items[k] = true 380 } 381 382 it.hasMapUpdated = true 383 384 return it 385 } 386 387 // AddItemsMap only add if the value is true 388 func (it *Hashset) AddItemsMap( 389 itemsMap map[string]bool, 390 ) *Hashset { 391 if itemsMap == nil { 392 return it 393 } 394 395 length := len(itemsMap) 396 397 if length > it.length || length > constants.ArbitraryCapacity100 { 398 it.AddCapacities(length*2, constants.ArbitraryCapacity100) 399 } 400 401 for k, isEnabled := range itemsMap { 402 if !isEnabled { 403 continue 404 } 405 406 it.items[k] = true 407 } 408 409 it.hasMapUpdated = true 410 411 return it 412 } 413 414 // AddItemsMapWgLock only add if the value is true 415 // Assume that wg already enqueued the job as wg.Add(...) done already. 416 func (it *Hashset) AddItemsMapWgLock( 417 itemsMap *map[string]bool, 418 wg *sync.WaitGroup, 419 ) *Hashset { 420 if itemsMap == nil { 421 return it 422 } 423 424 length := len(*itemsMap) 425 426 if length > it.length || length > constants.ArbitraryCapacity100 { 427 it.AddCapacitiesLock(length*2, constants.ArbitraryCapacity100) 428 } 429 430 for k, isEnabled := range *itemsMap { 431 if !isEnabled { 432 continue 433 } 434 435 it.Lock() 436 it.items[k] = true 437 it.Unlock() 438 } 439 440 wg.Done() 441 442 it.hasMapUpdated = true 443 444 return it 445 } 446 447 func (it *Hashset) AddHashsetWgLock( 448 hashsetAdd *Hashset, 449 wg *sync.WaitGroup, 450 ) *Hashset { 451 if hashsetAdd == nil { 452 return it 453 } 454 455 length := hashsetAdd.LengthLock() 456 457 if length > it.length || length > constants.ArbitraryCapacity100 { 458 it.AddCapacitiesLock(length*2, constants.ArbitraryCapacity100) 459 } 460 461 it.Lock() 462 for k := range hashsetAdd.items { 463 it.items[k] = true 464 } 465 466 it.Unlock() 467 wg.Done() 468 469 it.hasMapUpdated = true 470 471 return it 472 } 473 474 func (it *Hashset) AddStringsPtr(keys *[]string) *Hashset { 475 if keys == nil { 476 return it 477 } 478 479 for _, key := range *keys { 480 it.items[key] = true 481 } 482 483 it.hasMapUpdated = true 484 485 return it 486 } 487 488 func (it *Hashset) AddStrings(keys []string) *Hashset { 489 if len(keys) == 0 { 490 return it 491 } 492 493 return it.AddStringsPtr(&keys) 494 } 495 496 func (it *Hashset) AddSimpleSlice(simpleSlice *SimpleSlice) *Hashset { 497 if simpleSlice.IsEmpty() { 498 return it 499 } 500 501 return it.AddStringsPtr(&simpleSlice.Items) 502 } 503 504 func (it *Hashset) AddStringsPtrLock(keys *[]string) *Hashset { 505 if keys == nil { 506 return it 507 } 508 509 it.Lock() 510 for _, key := range *keys { 511 it.items[key] = true 512 } 513 514 it.Unlock() 515 516 it.hasMapUpdated = true 517 518 return it 519 } 520 521 func (it *Hashset) Adds(keys ...string) *Hashset { 522 if keys == nil { 523 return it 524 } 525 526 for _, key := range keys { 527 it.items[key] = true 528 } 529 530 it.hasMapUpdated = true 531 532 return it 533 } 534 535 func (it *Hashset) AddCollection( 536 collection *Collection, 537 ) *Hashset { 538 if collection == nil || collection.IsEmpty() { 539 return it 540 } 541 542 for _, element := range collection.items { 543 it.items[element] = true 544 } 545 546 it.hasMapUpdated = true 547 548 return it 549 } 550 551 func (it *Hashset) AddCollections( 552 collections ...*Collection, 553 ) *Hashset { 554 if collections == nil { 555 return it 556 } 557 558 for _, collection := range collections { 559 if collection == nil || collection.IsEmpty() { 560 continue 561 } 562 563 for _, element := range collection.items { 564 it.items[element] = true 565 } 566 } 567 568 it.hasMapUpdated = true 569 570 return it 571 } 572 573 func (it *Hashset) AddsAnyUsingFilter( 574 filter IsStringFilter, 575 anys ...interface{}, 576 ) *Hashset { 577 if anys == nil { 578 return it 579 } 580 581 for i, any := range anys { 582 if any == nil { 583 continue 584 } 585 586 anyStr := fmt.Sprintf(constants.SprintValueFormat, any) 587 result, isKeep, isBreak := filter(anyStr, i) 588 589 if isKeep { 590 it.items[result] = true 591 it.hasMapUpdated = true 592 } 593 594 if isBreak { 595 return it 596 } 597 } 598 599 return it 600 } 601 602 func (it *Hashset) AddsAnyUsingFilterLock( 603 filter IsStringFilter, 604 anys ...interface{}, 605 ) *Hashset { 606 if anys == nil { 607 return it 608 } 609 610 for i, any := range anys { 611 if any == nil { 612 continue 613 } 614 615 anyStr := fmt.Sprintf( 616 constants.SprintValueFormat, 617 any) 618 619 result, isKeep, isBreak := filter(anyStr, i) 620 621 if isKeep { 622 it.Lock() 623 it.items[result] = true 624 it.Unlock() 625 626 it.hasMapUpdated = true 627 } 628 629 if isBreak { 630 return it 631 } 632 } 633 634 return it 635 } 636 637 func (it *Hashset) AddsUsingFilter( 638 filter IsStringFilter, 639 keys ...string, 640 ) *Hashset { 641 if keys == nil { 642 return it 643 } 644 645 for i, key := range keys { 646 result, isKeep, isBreak := filter(key, i) 647 648 if isKeep { 649 it.items[result] = true 650 it.hasMapUpdated = true 651 } 652 653 if isBreak { 654 return it 655 } 656 } 657 658 return it 659 } 660 661 func (it *Hashset) AddLock(key string) *Hashset { 662 it.Lock() 663 defer it.Unlock() 664 665 it.items[key] = true 666 it.hasMapUpdated = true 667 668 return it 669 } 670 671 func (it *Hashset) HasAnyItem() bool { 672 return it != nil && it.Length() > 0 673 } 674 675 func (it *Hashset) IsMissing(key string) bool { 676 _, isFound := it.items[key] 677 678 return !isFound 679 } 680 681 func (it *Hashset) IsMissingLock(key string) bool { 682 it.Lock() 683 _, isFound := it.items[key] 684 it.Unlock() 685 686 return !isFound 687 } 688 689 func (it *Hashset) Has(key string) bool { 690 isSet, isFound := it.items[key] 691 692 return isFound && isSet 693 } 694 695 func (it *Hashset) HasLock(key string) bool { 696 it.Lock() 697 isSet, isFound := it.items[key] 698 it.Unlock() 699 700 return isFound && isSet 701 } 702 703 func (it *Hashset) HasAllStrings(keys []string) bool { 704 for _, key := range keys { 705 isSet, isFound := it.items[key] 706 707 if !(isFound && isSet) { 708 // not found 709 return false 710 } 711 } 712 713 // all found. 714 return true 715 } 716 717 // HasAllCollectionItems return false on items is nil or Empty. 718 func (it *Hashset) HasAllCollectionItems( 719 collection *Collection, 720 ) bool { 721 if collection == nil || collection.IsEmpty() { 722 return false 723 } 724 725 return it.HasAllStrings(collection.List()) 726 } 727 728 func (it *Hashset) HasAll(keys ...string) bool { 729 for _, key := range keys { 730 isSet, isFound := it.items[key] 731 732 if !(isFound && isSet) { 733 // not found 734 return false 735 } 736 } 737 738 // all found. 739 return true 740 } 741 742 func (it *Hashset) IsAllMissing(keys ...string) bool { 743 for _, key := range keys { 744 isSet, isFound := it.items[key] 745 746 if isFound && isSet { 747 // found 748 return false 749 } 750 } 751 752 // all not found. 753 return true 754 } 755 756 func (it *Hashset) HasAny(keys ...string) bool { 757 for _, key := range keys { 758 isSet, isFound := it.items[key] 759 760 if isFound && isSet { 761 // any found 762 return true 763 } 764 } 765 766 // all not found. 767 return false 768 } 769 770 func (it *Hashset) HasWithLock(key string) bool { 771 it.Lock() 772 defer it.Unlock() 773 774 isSet, isFound := it.items[key] 775 776 return isFound && isSet 777 } 778 779 func (it *Hashset) OrderedList() []string { 780 if it.IsEmpty() { 781 return []string{} 782 } 783 784 return it. 785 Collection(). 786 SortedAsc(). 787 items 788 } 789 790 func (it *Hashset) SafeStrings() []string { 791 if it.IsEmpty() { 792 return []string{} 793 } 794 795 return it.List() 796 } 797 798 func (it *Hashset) Lines() []string { 799 if it.IsEmpty() { 800 return []string{} 801 } 802 803 return it.List() 804 } 805 806 // GetFilteredItems must return slice. 807 func (it *Hashset) GetFilteredItems( 808 filter IsStringFilter, 809 ) *[]string { 810 if it.IsEmpty() { 811 return &([]string{}) 812 } 813 814 filteredList := make( 815 []string, 816 0, 817 it.Length()) 818 819 i := 0 820 for key := range it.items { 821 result, isKeep, isBreak := filter(key, i) 822 i++ 823 824 if !isKeep { 825 continue 826 } 827 828 filteredList = append( 829 filteredList, 830 result) 831 832 if isBreak { 833 return &filteredList 834 } 835 } 836 837 return &filteredList 838 } 839 840 // GetFilteredCollection must return items. 841 func (it *Hashset) GetFilteredCollection( 842 filter IsStringFilter, 843 ) *Collection { 844 if it.IsEmpty() { 845 return Empty.Collection() 846 } 847 848 filteredList := make( 849 []string, 850 0, 851 it.Length()) 852 853 i := 0 854 for key := range it.items { 855 result, isKeep, isBreak := filter(key, i) 856 i++ 857 858 if !isKeep { 859 continue 860 } 861 862 filteredList = append( 863 filteredList, 864 result) 865 866 if isBreak { 867 return New.Collection.StringsOptions( 868 false, 869 filteredList) 870 } 871 } 872 873 return New.Collection.StringsOptions( 874 false, 875 filteredList) 876 } 877 878 // GetAllExceptHashset Get all hashset items except the mentioned ones in anotherHashset. 879 // Always returns a copy of new strings. 880 // It is like set A - B 881 // Set A = this Hashset 882 // Set B = anotherHashset given in parameters. 883 func (it *Hashset) GetAllExceptHashset( 884 anotherHashset *Hashset, 885 ) []string { 886 if anotherHashset == nil || anotherHashset.IsEmpty() { 887 return it.List() 888 } 889 890 finalList := make( 891 []string, 892 0, 893 it.Length()) 894 895 for item := range it.items { 896 if anotherHashset.Has(item) { 897 continue 898 } 899 900 finalList = append( 901 finalList, 902 item) 903 } 904 905 return finalList 906 } 907 908 // GetAllExcept Get all hashset items except the mentioned ones in items. 909 // Always returns a copy of new strings. 910 // It is like set A - B 911 // Set A = this Hashset 912 // Set B = items given in parameters. 913 func (it *Hashset) GetAllExcept( 914 items []string, 915 ) []string { 916 if items == nil { 917 return it.List() 918 } 919 920 newHashset := New.Hashset.Strings( 921 items) 922 923 return it.GetAllExceptHashset( 924 newHashset) 925 } 926 927 func (it *Hashset) GetAllExceptSpread( 928 items ...string, 929 ) []string { 930 if items == nil { 931 return it.List() 932 } 933 934 newHashset := New.Hashset.Strings( 935 items) 936 937 return it.GetAllExceptHashset( 938 newHashset) 939 } 940 941 // GetAllExceptCollection Get all hashset items except the mentioned ones in collection. 942 // Always returns a copy of new strings. 943 // It is like set A - B 944 // Set A = this Hashset 945 // Set B = collection given in parameters. 946 func (it *Hashset) GetAllExceptCollection( 947 collection *Collection, 948 ) []string { 949 if collection == nil { 950 return it.List() 951 } 952 953 return it.GetAllExceptHashset( 954 collection.HashsetAsIs()) 955 } 956 957 // GetAllExceptCollectionPtr Get all hashset items except the mentioned ones in collectionPtr. 958 // Always returns a copy of new strings. 959 // It is like set A - B 960 // Set A = this Hashset 961 // Set B = collectionPtr given in parameters. 962 func (it *Hashset) GetAllExceptCollectionPtr( 963 collectionPtr *CollectionPtr, 964 ) []string { 965 if collectionPtr == nil { 966 return it.List() 967 } 968 969 return it.GetAllExceptHashset( 970 collectionPtr.HashsetAsIs()) 971 } 972 973 func (it *Hashset) Items() map[string]bool { 974 return it.items 975 } 976 977 func (it *Hashset) List() []string { 978 return *it.ListPtr() 979 } 980 981 func (it *Hashset) MapStringAny() map[string]interface{} { 982 if it.IsEmpty() { 983 return map[string]interface{}{} 984 } 985 986 newMap := make( 987 map[string]interface{}, 988 it.Length()+1) 989 990 for name, isSet := range it.items { 991 newMap[name] = isSet 992 } 993 994 return newMap 995 } 996 997 func (it *Hashset) MapStringAnyDiff() mapdiffinternal.MapStringAnyDiff { 998 return it.MapStringAny() 999 } 1000 1001 func (it *Hashset) JoinSorted(joiner string) string { 1002 if it.IsEmpty() { 1003 return constants.EmptyString 1004 } 1005 1006 list := it.ListPtr() 1007 sort.Strings(*list) 1008 1009 return strings.Join(*list, joiner) 1010 } 1011 1012 func (it *Hashset) ListPtrSortedAsc() []string { 1013 list := it.ListPtr() 1014 sort.Strings(*list) 1015 1016 return *list 1017 } 1018 1019 func (it *Hashset) ListPtrSortedDsc() []string { 1020 list := it.ListPtr() 1021 sort.Strings(*list) 1022 1023 return *stringslice.InPlaceReverse(list) 1024 } 1025 1026 func (it *Hashset) ListPtr() *[]string { 1027 if it.hasMapUpdated || it.cachedList == nil { 1028 it.setCached() 1029 } 1030 1031 return &it.cachedList 1032 } 1033 1034 func (it *Hashset) Clear() *Hashset { 1035 if it == nil { 1036 return it 1037 } 1038 1039 it.items = nil 1040 it.items = make(map[string]bool) 1041 it.cachedList = []string{} 1042 it.hasMapUpdated = true 1043 1044 return it 1045 } 1046 1047 func (it *Hashset) Dispose() { 1048 if it == nil { 1049 return 1050 } 1051 1052 it.Clear() 1053 it.items = nil 1054 it.cachedList = nil 1055 } 1056 1057 // ListCopyPtrLock a slice must returned 1058 func (it *Hashset) ListCopyPtrLock() *[]string { 1059 it.Lock() 1060 defer it.Unlock() 1061 cloned := *it.ListPtr() 1062 1063 return &cloned 1064 } 1065 1066 func (it *Hashset) setCached() { 1067 length := it.Length() 1068 list := make([]string, length) 1069 1070 i := 0 1071 1072 for key := range it.items { 1073 list[i] = key 1074 i++ 1075 } 1076 1077 it.hasMapUpdated = false 1078 it.cachedList = list 1079 } 1080 1081 // ToLowerSet CreateUsingAliasMap a new items with all lower strings 1082 func (it *Hashset) ToLowerSet() *Hashset { 1083 length := it.Length() 1084 newMap := make(map[string]bool, length) 1085 1086 var toLower string 1087 for key, isEnabled := range it.items { 1088 toLower = strings.ToLower(key) 1089 newMap[toLower] = isEnabled 1090 } 1091 1092 return New.Hashset.UsingMapOption( 1093 length, 1094 false, 1095 newMap, 1096 ) 1097 } 1098 1099 func (it *Hashset) Length() int { 1100 if it == nil { 1101 return 0 1102 } 1103 1104 if it.hasMapUpdated { 1105 it.length = len(it.items) 1106 } 1107 1108 return it.length 1109 } 1110 1111 func (it *Hashset) LengthLock() int { 1112 it.Lock() 1113 defer it.Unlock() 1114 1115 return it.Length() 1116 } 1117 1118 func (it *Hashset) IsEqualsPtrLock(another *Hashset) bool { 1119 it.Lock() 1120 defer it.Unlock() 1121 1122 return it.IsEqualsPtr(another) 1123 } 1124 1125 func (it *Hashset) IsEqualsPtr(another *Hashset) bool { 1126 if it == nil && another == nil { 1127 return true 1128 } 1129 1130 if it == nil || another == nil { 1131 return false 1132 } 1133 1134 if it == another { 1135 // ptr same 1136 return true 1137 } 1138 1139 if it.IsEmpty() && another.IsEmpty() { 1140 return true 1141 } 1142 1143 if it.IsEmpty() || another.IsEmpty() { 1144 return false 1145 } 1146 1147 leftLength := it.Length() 1148 rightLength := another.Length() 1149 1150 if leftLength != rightLength { 1151 return false 1152 } 1153 1154 for key := range it.items { 1155 isRes, has := another.items[key] 1156 1157 if !has || !isRes { 1158 return false 1159 } 1160 } 1161 1162 return true 1163 } 1164 1165 func (it *Hashset) Remove(key string) *Hashset { 1166 delete(it.items, key) 1167 it.hasMapUpdated = true 1168 1169 return it 1170 } 1171 1172 func (it *Hashset) SafeRemove(key string) *Hashset { 1173 if it.Has(key) { 1174 delete(it.items, key) 1175 it.hasMapUpdated = true 1176 } 1177 1178 return it 1179 } 1180 1181 func (it *Hashset) RemoveWithLock(key string) *Hashset { 1182 it.Lock() 1183 defer it.Unlock() 1184 1185 it.Remove(key) 1186 1187 return it 1188 } 1189 1190 func (it Hashset) String() string { 1191 if it.IsEmpty() { 1192 return commonJoiner + NoElements 1193 } 1194 1195 return commonJoiner + 1196 strings.Join( 1197 it.List(), 1198 commonJoiner) 1199 } 1200 1201 func (it *Hashset) StringLock() string { 1202 if it.IsEmptyLock() { 1203 return commonJoiner + NoElements 1204 } 1205 1206 it.Lock() 1207 defer it.Unlock() 1208 1209 return commonJoiner + 1210 strings.Join( 1211 *it.ListPtr(), 1212 commonJoiner) 1213 } 1214 1215 func (it Hashset) Join( 1216 joiner string, 1217 ) string { 1218 return strings.Join(*it.ListPtr(), joiner) 1219 } 1220 1221 func (it Hashset) NonEmptyJoins( 1222 joiner string, 1223 ) string { 1224 return stringslice.NonEmptyJoinPtr( 1225 it.ListPtr(), 1226 joiner) 1227 } 1228 1229 func (it Hashset) NonWhitespaceJoins( 1230 joiner string, 1231 ) string { 1232 return stringslice.NonWhitespaceJoinPtr( 1233 it.ListPtr(), 1234 joiner) 1235 } 1236 1237 //goland:noinspection GoLinterLocal 1238 func (it Hashset) JsonModel() map[string]bool { 1239 if it.IsEmpty() { 1240 return map[string]bool{} 1241 } 1242 1243 return it.items 1244 } 1245 1246 //goland:noinspection GoLinterLocal 1247 func (it Hashset) JsonModelAny() interface{} { 1248 return it.JsonModel() 1249 } 1250 1251 func (it Hashset) MarshalJSON() ([]byte, error) { 1252 return json.Marshal(it.JsonModel()) 1253 } 1254 1255 func (it *Hashset) UnmarshalJSON(data []byte) error { 1256 var dataModelItems map[string]bool 1257 err := json.Unmarshal(data, &dataModelItems) 1258 1259 if err == nil { 1260 it.items = dataModelItems 1261 it.length = -1 1262 it.hasMapUpdated = true 1263 it.isEmptySet = false 1264 } 1265 1266 return err 1267 } 1268 1269 func (it Hashset) Json() corejson.Result { 1270 return corejson.New(it) 1271 } 1272 1273 func (it Hashset) JsonPtr() *corejson.Result { 1274 return corejson.NewPtr(it) 1275 } 1276 1277 // ParseInjectUsingJson It will not update the self but creates a new one. 1278 func (it *Hashset) ParseInjectUsingJson( 1279 jsonResult *corejson.Result, 1280 ) (*Hashset, error) { 1281 err := jsonResult.Unmarshal(it) 1282 1283 if err != nil { 1284 return New.Hashset.Empty(), err 1285 } 1286 1287 return it, nil 1288 } 1289 1290 // ParseInjectUsingJsonMust Panic if error 1291 func (it *Hashset) ParseInjectUsingJsonMust( 1292 jsonResult *corejson.Result, 1293 ) *Hashset { 1294 hashSet, err := it.ParseInjectUsingJson(jsonResult) 1295 1296 if err != nil { 1297 panic(err) 1298 } 1299 1300 return hashSet 1301 } 1302 1303 func (it *Hashset) AsJsonContractsBinder() corejson.JsonContractsBinder { 1304 return it 1305 } 1306 1307 func (it *Hashset) AsJsoner() corejson.Jsoner { 1308 return it 1309 } 1310 1311 func (it *Hashset) JsonParseSelfInject( 1312 jsonResult *corejson.Result, 1313 ) error { 1314 _, err := it.ParseInjectUsingJson( 1315 jsonResult, 1316 ) 1317 1318 return err 1319 } 1320 1321 func (it *Hashset) AsJsonParseSelfInjector() corejson.JsonParseSelfInjector { 1322 return it 1323 } 1324 1325 func (it *Hashset) AsJsonMarshaller() corejson.JsonMarshaller { 1326 return it 1327 } 1328 1329 func (it *Hashset) DistinctDiffLinesRaw( 1330 rightLines ...string, 1331 ) []string { 1332 isLeftEmpty := it.IsEmpty() 1333 1334 if isLeftEmpty && len(rightLines) == 0 { 1335 return []string{} 1336 } 1337 1338 if !isLeftEmpty && len(rightLines) == 0 { 1339 return it.List() 1340 } 1341 1342 if isLeftEmpty && len(rightLines) > 0 { 1343 return rightLines 1344 } 1345 1346 diffLines := make( 1347 []string, 1348 0, 1349 it.Length()+len(rightLines)) 1350 1351 for _, rightItem := range rightLines { 1352 _, has := it.items[rightItem] 1353 1354 if !has { 1355 diffLines = append(diffLines, rightItem) 1356 } 1357 } 1358 1359 rightHashset := converters.StringsTo.Hashset( 1360 rightLines) 1361 1362 for leftItem := range it.items { 1363 _, has := rightHashset[leftItem] 1364 1365 if !has { 1366 diffLines = append(diffLines, leftItem) 1367 } 1368 } 1369 1370 return diffLines 1371 } 1372 1373 func (it *Hashset) DistinctDiffHashset( 1374 rightHashset *Hashset, 1375 ) map[string]bool { 1376 return it.DistinctDiffLines( 1377 rightHashset.Lines()...) 1378 } 1379 1380 func (it *Hashset) DistinctDiffLines( 1381 rightLines ...string, 1382 ) map[string]bool { 1383 isLeftEmpty := it.IsEmpty() 1384 1385 if isLeftEmpty && len(rightLines) == 0 { 1386 return map[string]bool{} 1387 } 1388 1389 if !isLeftEmpty && len(rightLines) == 0 { 1390 return it.Items() 1391 } 1392 1393 if isLeftEmpty && len(rightLines) > 0 { 1394 return converters.StringsTo.Hashset(rightLines) 1395 } 1396 1397 diffMap := make( 1398 map[string]bool, 1399 it.Length()+len(rightLines)) 1400 1401 for _, rightItem := range rightLines { 1402 _, has := it.items[rightItem] 1403 1404 if !has { 1405 diffMap[rightItem] = true 1406 } 1407 } 1408 1409 rightHashset := converters.StringsTo.Hashset( 1410 rightLines) 1411 1412 for leftItem := range it.items { 1413 _, has := rightHashset[leftItem] 1414 1415 if !has { 1416 diffMap[leftItem] = true 1417 } 1418 } 1419 1420 return diffMap 1421 } 1422 1423 func (it *Hashset) Serialize() ([]byte, error) { 1424 return corejson.Serialize.Raw(it) 1425 } 1426 1427 func (it *Hashset) Deserialize(toPtr interface{}) (parsingErr error) { 1428 return it.JsonPtr().Deserialize(toPtr) 1429 }