github.com/m4gshm/gollections@v0.0.13-0.20240331203319-a34a86e58a24/internal/docs/readme.adoc (about)

     1  = Gollections
     2  
     3  == Gollections
     4  
     5  Gollections is set of functions for link:#slices[slices], link:#maps[maps] and additional implementations of data structures such as link:#mutable-collections[ordered map] or link:#mutable-collections[set] aimed to reduce boilerplate code.
     6  
     7  Supports Go version 1.21.
     8  
     9  For example, it's need to group some link:./internal/examples/boilerplate/user_type.go[users] by their role names converted to lowercase:
    10  [source,go]
    11  ----
    12  include::../examples/boilerplate/user_data.go[lines=3..-1]
    13  ----
    14  
    15  You can make clear code, extensive, but without dependencies:
    16  [source,go]
    17  ----
    18  include::../examples/boilerplate/slice_namesbyRole_old_test.go[lines=11..26,indent=0]
    19  ----
    20  
    21  Or you can write more compact code using the collections API, like:
    22  [source,go]
    23  ----
    24  import "github.com/m4gshm/gollections/slice/convert"
    25  import "github.com/m4gshm/gollections/slice/group"
    26  include::../examples/boilerplate/slice_namesbyRole_new_test.go[lines=14..19,indent=0]
    27  ----
    28  
    29  === Installation
    30  
    31  [source,console]
    32  ----
    33  go get -u github.com/m4gshm/gollections
    34  ----
    35  
    36  === Slices
    37  
    38  [source,go]
    39  ----
    40  include::../examples/boilerplate/slice_filter_convert_reduce_test.go[lines=15..22,indent=0]
    41  ----
    42  
    43  In the example is used only small set of slice functions as link:#slicefilter[slice.Filter], link:#sliceconv[slice.Conv] link:#sliceconvert#[slice.Convert], and link:#slicereduce[slice.Reduce]. More you can look in the link:./slice/api.go[slice] package.
    44  
    45  ==== Shortcut packages
    46  
    47  [source,go]
    48  ----
    49  include::../examples/boilerplate/slice_filter_convert_reduce_short_test.go[lines=18..20,indent=0]
    50  ----
    51  
    52  This is a shorter version of the previous example that used short aliases link:#sumof[sum.Of] and link:#operations-chain-functions[filter.AndConvert]. More shortcuts you can find by exploring slices link:./slice[subpackages].
    53  
    54  *Be careful* when use several slice functions subsequently like [source,go]`slice.Filter(slice.Convert(...))`. This can lead to unnecessary RAM consumption. Consider link:#loop-kvloop-and-breakable-versions-breakloop-breakkvloop[loop] instead of slice API.
    55  
    56  ==== Main slice functions
    57  ===== Instantiators
    58  ====== slice.Of
    59  [source,go]
    60  ----
    61  include::../examples/sliceexamples/slice_Of_test.go[lines=11..13,indent=0]
    62  ----
    63  ====== range_.Of
    64  [source,go]
    65  ----
    66  import "github.com/m4gshm/gollections/slice/range_"
    67  include::../examples/sliceexamples/range_Of_test.go[lines=11..15,indent=0]
    68  ----
    69  ====== range_.Closed
    70  [source,go]
    71  ----
    72  include::../examples/sliceexamples/range_Closed_test.go[lines=12..16,indent=0]
    73  ----
    74  ===== Sorters
    75  ====== sort.Asc, sort.Desc 
    76  [source,go]
    77  ----
    78  // sorting in-place API
    79  import "github.com/m4gshm/gollections/slice/sort"
    80  include::../examples/sliceexamples/sort_Asc_Desc_test.go[lines=12..15,indent=0]
    81  ----
    82  ====== sort.By, sort.ByDesc
    83  [source,go]
    84  ----
    85  // sorting copied slice API does not change the original slice
    86  import "github.com/m4gshm/gollections/slice/clone/sort"
    87  
    88  include::../examples/sliceexamples/data_users_test.go[lines=3..10,indent=0]
    89  include::../examples/sliceexamples/clone_sort_By_test.go[lines=12..18,indent=0]
    90  ----
    91  ===== To map converters
    92  ====== group.Of
    93  [source,go]
    94  ----
    95  import "github.com/m4gshm/gollections/convert/as"
    96  import "github.com/m4gshm/gollections/expr/use"
    97  import "github.com/m4gshm/gollections/slice/group"
    98  include::../examples/sliceexamples/group_Of_test.go[lines=16..22,indent=0]
    99  ----
   100  ====== group.ByMultipleKeys
   101  [source,go]
   102  ----
   103  import "github.com/m4gshm/gollections/slice/convert"
   104  import "github.com/m4gshm/gollections/slice/group"
   105  include::../examples/boilerplate/slice_namesbyRole_new_test.go[lines=14..19,indent=0]
   106  ----
   107  ====== slice.ToMap, slice.ToMapResolv
   108  [source,go]
   109  ----
   110  import (
   111      "github.com/m4gshm/gollections/map_/resolv"
   112      "github.com/m4gshm/gollections/op"
   113      "github.com/m4gshm/gollections/slice"
   114  )
   115  include::../examples/sliceexamples/slice_ToMapResolv_test.go[lines=14..22,indent=0]
   116  ----
   117  ===== Reducers
   118  ====== sum.Of
   119  [source,go]
   120  ----
   121  import "github.com/m4gshm/gollections/op/sum"
   122  include::../examples/sliceexamples/sum_Of_test.go[lines=12..14,indent=0]
   123  ----
   124  ====== slice.Reduce
   125  [source,go]
   126  ----
   127  include::../examples/sliceexamples/slice_Reduce_test.go[lines=12..15,indent=0]
   128  ----
   129  ====== slice.First
   130  [source,go]
   131  ----
   132  import "github.com/m4gshm/gollections/predicate/more"
   133  import "github.com/m4gshm/gollections/slice"
   134  include::../examples/sliceexamples/slice_First_test.go[lines=13..15,indent=0]
   135  ----
   136  ====== slice.Last
   137  [source,go]
   138  ----
   139  import "github.com/m4gshm/gollections/predicate/less"
   140  import "github.com/m4gshm/gollections/slice"
   141  include::../examples/sliceexamples/slice_Last_test.go[lines=13..15,indent=0]
   142  ----
   143  ===== Converters
   144  ====== slice.Convert
   145  [source,go]
   146  ----
   147  include::../examples/sliceexamples/slice_Convert_test.go[lines=13..16,indent=0]
   148  ----
   149  ====== slice.Conv
   150  [source,go]
   151  ----
   152  include::../examples/sliceexamples/slice_Conv_test.go[lines=13..16,indent=0]
   153  ----
   154  ====== slice.Filter
   155  [source,go]
   156  ----
   157  import "github.com/m4gshm/gollections/predicate/exclude"
   158  import "github.com/m4gshm/gollections/predicate/one"
   159  import "github.com/m4gshm/gollections/slice"
   160  include::../examples/sliceexamples/slice_Filter.go[lines=14..17,indent=0]
   161  ----
   162  ====== slice.Flat
   163  [source,go]
   164  ----
   165  import "github.com/m4gshm/gollections/convert/as"
   166  import "github.com/m4gshm/gollections/slice"
   167  include::../examples/sliceexamples/slice_Flat_test.go[lines=13..16,indent=0]
   168  ----
   169  ===== Operations chain functions
   170  * convert.AndReduce, conv.AndReduce 
   171  * convert.AndFilter 
   172  * filter.AndConvert
   173  
   174  These functions combine converters, filters and reducers.
   175  
   176  === Maps
   177  ==== Main map functions
   178  ===== Instantiators
   179  ====== clone.Of
   180  [source,go]
   181  ----
   182  import "github.com/m4gshm/gollections/map_/clone"
   183  include::../examples/mapexamples/clone_Of_test.go[lines=13..28,indent=0]
   184  ----
   185  ====== clone.Deep
   186  [source,go]
   187  ----
   188  import "github.com/m4gshm/gollections/map_/clone"
   189  include::../examples/mapexamples/clone_Deep_test.go[lines=13..30,indent=0]
   190  ----
   191  ===== Keys, values exrtractors
   192  ====== map_.Keys, map_.Values
   193  [source,go]
   194  ----
   195  include::../examples/mapexamples/map_Keys_Values_test.go[lines=15..23,indent=0]
   196  ----
   197  ===== Converters
   198  ====== map_.ConvertKeys
   199  [source,go]
   200  ----
   201  include::../examples/mapexamples/map_ConvertKeys_test.go[lines=17..22,indent=0]
   202  ----
   203  ====== map_.ConvertValues
   204  [source,go]
   205  ----
   206  include::../examples/mapexamples/map_ConvertValues_test.go[lines=17..22,indent=0]
   207  ----
   208  ====== map_.Convert
   209  [source,go]
   210  ----
   211  include::../examples/mapexamples/map_Convert_test.go[lines=17..22,indent=0]
   212  ----
   213  ====== map_.Conv
   214  [source,go]
   215  ----
   216  include::../examples/mapexamples/map_Conv_test.go[lines=17..22,indent=0]
   217  ----
   218  ====== map_.ToSlice
   219  [source,go]
   220  ----
   221  include::../examples/mapexamples/map_ToSlice_test.go[lines=19..24,indent=0]
   222  ----
   223  
   224  [#loop]
   225  === link:./loop/api.go[loop], link:./kv/loop/api.go[kv/loop] and breakable versions link:./break/loop/api.go[break/loop], link:./break/kv/loop/api.go[break/kv/loop]
   226  
   227  Low-level API for iteration based on next functions:
   228  
   229  [source,go]
   230  ----
   231  include::../examples/loopexamples/type.go[lines=2..9,indent=0]
   232  ----
   233  
   234  The `Loop` function retrieves a next element from a dataset and returns ``ok==true`` if successful. +
   235  The `KVLoop` behaves similar but returns a key/value pair. +
   236  
   237  [source,go]
   238  ----
   239  include::../examples/loopexamples/loop_filter_convert_reduce_test.go[lines=13..18,indent=0]
   240  ----
   241  
   242  `BreakLoop` and `BreakKVLoop` are used for sources that can issue an error.
   243  
   244  [source,go]
   245  ----
   246  include::../examples/loopexamples/breakloop/loop_filter_convert_reduce_test.go[lines=13..19,indent=0]
   247  ----
   248  
   249  The API in most cases is similar to the link:./slice/api.go[slice] API but with delayed computation which means that the methods don't compute a result but only return a loop provider. The loop provider is type with a ``Next`` method that returns a next processed element.
   250  
   251  ==== Main loop functions
   252  ===== Instantiators
   253  ====== loop.Of, loop.S
   254  [source,go]
   255  ----
   256  import "github.com/m4gshm/gollections/loop"
   257  include::../examples/loopexamples/loop_Of_loop_S_test.go[lines=12..17,indent=0]
   258  ----
   259  ====== range_.Of
   260  [source,go]
   261  ----
   262  import "github.com/m4gshm/gollections/loop/range_"
   263  include::../examples/loopexamples/range_Of_test.go[lines=11..15,indent=0]
   264  ----
   265  ====== range_.Closed
   266  [source,go]
   267  ----
   268  include::../examples/loopexamples/range_Closed_test.go[lines=12..16,indent=0]
   269  ----
   270  ===== To map converters
   271  ====== group.Of
   272  [source,go]
   273  ----
   274  import "github.com/m4gshm/gollections/convert/as"
   275  import "github.com/m4gshm/gollections/expr/use"
   276  import "github.com/m4gshm/gollections/loop/group"
   277  include::../examples/loopexamples/group_Of_test.go[lines=16..22,indent=0]
   278  ----
   279  ====== loop.ToMap, loop.ToMapResolv
   280  [source,go]
   281  ----
   282  import (
   283      "github.com/m4gshm/gollections/map_/resolv"
   284      "github.com/m4gshm/gollections/op"
   285      "github.com/m4gshm/gollections/loop"
   286  )
   287  include::../examples/loopexamples/loop_ToMapResolv_test.go[lines=14..22,indent=0]
   288  ----
   289  ===== Reducers
   290  ====== sum.Of
   291  [source,go]
   292  ----
   293  import "github.com/m4gshm/gollections/op/sum"
   294  include::../examples/loopexamples/sum_Of_test.go[lines=13..15,indent=0]
   295  ----
   296  ====== loop.Reduce
   297  [source,go]
   298  ----
   299  include::../examples/loopexamples/loop_Reduce_test.go[lines=12..15,indent=0]
   300  ----
   301  ====== loop.First
   302  [source,go]
   303  ----
   304  import "github.com/m4gshm/gollections/predicate/more"
   305  import "github.com/m4gshm/gollections/loop"
   306  include::../examples/loopexamples/loop_First_test.go[lines=13..15,indent=0]
   307  ----
   308  ===== Converters
   309  ====== loop.Convert
   310  [source,go]
   311  ----
   312  include::../examples/loopexamples/loop_Convert_test.go[lines=12..15,indent=0]
   313  ----
   314  ====== loop.Conv
   315  [source,go]
   316  ----
   317  include::../examples/loopexamples/loop_Conv_test.go[lines=13..16,indent=0]
   318  ----
   319  ====== loop.Filter
   320  [source,go]
   321  ----
   322  import "github.com/m4gshm/gollections/predicate/exclude"
   323  import "github.com/m4gshm/gollections/predicate/one"
   324  import "github.com/m4gshm/gollections/loop"
   325  include::../examples/loopexamples/loop_Filter.go[lines=14..17,indent=0]
   326  ----
   327  ====== loop.Flat
   328  [source,go]
   329  ----
   330  import "github.com/m4gshm/gollections/convert/as"
   331  import "github.com/m4gshm/gollections/loop"
   332  include::../examples/loopexamples/loop_Flat_test.go[lines=13..16,indent=0]
   333  ----
   334  ===== Operations chain functions
   335  * convert.AndReduce, conv.AndReduce 
   336  * convert.AndFilter 
   337  * filter.AndConvert
   338  
   339  These functions combine converters, filters and reducers.
   340  
   341  ==== Iterating over loops
   342  * (only for go 1.22) Using rangefunc `All` like:
   343  
   344  [source,go]
   345  ----
   346  include::../examples/loopexamples/loop_iterating_go_1_22_test.go[lines=12..16,indent=0]
   347  ----
   348  don't forget exec `go env -w GOEXPERIMENT=rangefunc` before compile.
   349  
   350  * Using `for` statement like:
   351  
   352  [source,go]
   353  ----
   354  include::../examples/loopexamples/loop_iterating_test.go[lines=11..16,indent=0]
   355  ----
   356  
   357  * or
   358  
   359  [source,go]
   360  ----
   361  include::../examples/loopexamples/loop_iterating_test.go[lines=20..24,indent=0]
   362  ----
   363  
   364  * `ForEach` method
   365  
   366  [source,go]
   367  ----
   368  include::../examples/loopexamples/loop_iterating_test.go[lines=28..30,indent=0]
   369  ----
   370  
   371  * or `For` method that can be aborted by returning `Break` for expected completion, or another error otherwise.
   372  
   373  [source,go]
   374  ----
   375  include::../examples/loopexamples/loop_iterating_test.go[lines=34..42,indent=0]
   376  ----
   377  
   378  === Data structures
   379  ==== link:./collection/mutable/api.go[mutable] and link:./collection/immutable/api.go[immutable] collections
   380  
   381  Provides implelentations of link:./collection/iface.go#L25[Vector], link:./collection/iface.go#L35[Set] and link:./collection/iface.go#L41[Map].
   382  
   383  Mutables support content appending, updating and deleting (the ordered map implementation is not supported delete operations). +
   384  Immutables are read-only datasets.
   385  
   386  Detailed description of implementations xref:mutable-collections[below].
   387  
   388  === Additional API
   389  
   390  ==== link:./predicate/api.go[predicate] and breakable link:./predicate/api.go[break/predicate]
   391  
   392  Provides predicate builder api that used for filtering collection elements.
   393  
   394  [source,go]
   395  ----
   396  import "github.com/m4gshm/gollections/predicate/where"
   397  import "github.com/m4gshm/gollections/slice"
   398  include::../examples/boilerplate/predicate_test.go[lines=16..18,indent=0]
   399  ----
   400  
   401  It is used for computations where an error may occur.
   402  
   403  [source,go]
   404  ----
   405  include::../examples/loopexamples/breakloop/loop_filter_convert_reduce_test.go[lines=13..19,indent=0]
   406  ----
   407  
   408  ==== Expressions: link:./expr/use/api.go[use.If], link:./expr/get/api.go[get.If], link:#firstof[first.Of], link:#lastof[last.Of]
   409  
   410  Aimed to evaluate a value using conditions. May cause to make code shorter by not in all cases. +
   411  As example:
   412  
   413  [source,go]
   414  ----
   415  import "github.com/m4gshm/gollections/expr/use"
   416  include::../examples/boilerplate/expr_use_test.go[lines=15..22,indent=0]
   417  ----
   418  
   419  instead of:
   420  
   421  [source,go]
   422  ----
   423  include::../examples/boilerplate/expr_use_test.go[lines=27..38,indent=0]
   424  ----
   425  
   426  ===== first.Of
   427  [source,go]
   428  ----
   429  import "github.com/m4gshm/gollections/expr/first"
   430  import "github.com/m4gshm/gollections/predicate/more"
   431  include::../examples/expressionexamples/first_Of_test.go[lines=13..15,indent=0]
   432  ----
   433  ===== last.Of
   434  [source,go]
   435  ----
   436  import "github.com/m4gshm/gollections/expr/last"
   437  import "github.com/m4gshm/gollections/predicate/less"
   438  include::../examples/expressionexamples/last_Of_test.go[lines=13..15,indent=0]
   439  ----
   440  
   441  === Mutable collections
   442  
   443  Supports write operations (append, delete, replace).
   444  
   445    * link:./collection/mutable/vector/api.go[Vector] - the simplest based on built-in slice collection.
   446  
   447  [source,go]
   448  ----
   449  include::../examples/collection/mutable/vector.go[lines=10..11,indent=0]
   450  ----
   451  
   452    * link:./collection/mutable/set/api.go[Set] - collection of unique items, prevents duplicates.
   453  
   454  [source,go]
   455  ----
   456  include::../examples/collection/mutable/set.go[lines=10..11,indent=0]
   457  ----
   458  
   459    * link:./collection/mutable/map_/api.go[Map] - built-in map wrapper that supports xref:stream-functions[stream functions].
   460  
   461  [source,go]
   462  ----
   463  include::../examples/collection/mutable/map.go[lines=10..11,indent=0]
   464  ----
   465  
   466    * link:./collection/mutable/oset/api.go[OrderedSet] - collection of unique items, prevents duplicates, provides iteration in order of addition.
   467  
   468  [source,go]
   469  ----
   470  include::../examples/collection/mutable/oset.go[lines=10..11,indent=0]
   471  ----
   472  
   473    * link:./collection/mutable/omap/api.go[OrderedMap] - same as the Map, but supports iteration in the order in which elements are added.
   474  
   475  [source,go]
   476  ----
   477  include::../examples/collection/mutable/omap.go[lines=11..15,indent=0]
   478  ----
   479  
   480  ==== Immutable collections
   481  
   482  The same underlying interfaces but for read-only use cases.
   483  
   484  ==== Iterating over collections
   485  * (only for go 1.22) Using rangefunc `All` like:
   486  
   487  [source,go]
   488  ----
   489  include::../examples/collection/collection_iterating_go_1_22_test.go[lines=13..18,indent=0]
   490  ----
   491  * Using `for` statement like:
   492  
   493  [source,go]
   494  ----
   495  include::../examples/collection/collection_iterating_test.go[lines=12..18,indent=0]
   496  ----
   497  
   498  * or
   499  
   500  [source,go]
   501  ----
   502  include::../examples/collection/collection_iterating_test.go[lines=22..27,indent=0]
   503  ----
   504  
   505  * `ForEach` method
   506  
   507  [source,go]
   508  ----
   509  include::../examples/collection/collection_iterating_test.go[lines=31..34,indent=0]
   510  ----
   511  
   512  * or `For` method that can be aborted by returning `Break` for expected completion, or another error otherwise.
   513  
   514  [source,go]
   515  ----
   516  include::../examples/collection/collection_iterating_test.go[lines=38..47,indent=0]
   517  ----