github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/goutils/iterate/impl.go (about)

     1  /*
     2   * Copyright (c) 2021-present Sigma-Soft, Ltd.
     3   * @author: Nikolay Nikitin
     4   */
     5  
     6  package iterate
     7  
     8  // ForEach pass `enum` callback to `forEach` iterator to call `enum` for each data from slice-like structures
     9  func ForEach[T any](forEach ForEachFunction[T], enum func(T)) {
    10  	forEach(enum)
    11  }
    12  
    13  func ForEachError2Values[V1 any, V2 any](forEach ForEachFunction2Value[V1, V2], do func(V1, V2) error) (err error) {
    14  	forEach(func(v1 V1, v2 V2) {
    15  		if err != nil {
    16  			return
    17  		}
    18  		err = do(v1, v2)
    19  	})
    20  	return err
    21  }
    22  
    23  // Same as ForEachError but with an one addition arg
    24  func ForEachError1Arg[T any, A1 any](forEach ForEachFunction1Arg[T, A1], arg1 A1, do func(T) error) (err error) {
    25  	forEach(arg1, func(d T) {
    26  		if err != nil {
    27  			return
    28  		}
    29  		err = do(d)
    30  	})
    31  	return err
    32  }
    33  
    34  func ForEachError[T any](forEach ForEachFunction[T], do func(T) error) (err error) {
    35  	forEach(func(d T) {
    36  		if err != nil {
    37  			return
    38  		}
    39  		err = do(d)
    40  	})
    41  	return err
    42  }
    43  
    44  // Slice is a function type wrapper for naked slices.
    45  // Slice result can be passed as a first argument to `ForEach`, `FindFirst` and `FindFirstError` routines
    46  func Slice[T any](slice []T) ForEachFunction[T] {
    47  	return func(enum func(T)) {
    48  		for _, d := range slice {
    49  			enum(d)
    50  		}
    51  	}
    52  }
    53  
    54  // FindFirst find first data by `forEach` iterator, using test function.
    55  func FindFirst[T any](forEach ForEachFunction[T], test func(T) bool) (ok bool, data T) {
    56  	forEach(func(d T) {
    57  		if ok {
    58  			return
    59  		}
    60  		if ok = test(d); ok {
    61  			data = d
    62  		}
    63  	})
    64  	return ok, data
    65  }
    66  
    67  // FindFirstData find first occurs of specified `data` by `forEach` iterator
    68  func FindFirstData[T comparable](forEach ForEachFunction[T], data T) (ok bool, idx int) {
    69  	idx = -1
    70  	i := 0
    71  	forEach(func(d T) {
    72  		if ok {
    73  			return
    74  		}
    75  		if ok = (d == data); ok {
    76  			idx = i
    77  		}
    78  		i++
    79  	})
    80  	return ok, idx
    81  }
    82  
    83  // FindFirstError find first data with error by `forEach` iterator, using test function.
    84  func FindFirstError[T any](forEach ForEachFunction[T], test func(T) error) (data T, err error) {
    85  	forEach(func(d T) {
    86  		if err != nil {
    87  			return
    88  		}
    89  		if err = test(d); err != nil {
    90  			data = d
    91  		}
    92  	})
    93  	return data, err
    94  }
    95  
    96  // ForEachMap pass `enum` callback to `forEach` iterator to call `enum` for each key-data pairs from map-like structures
    97  func ForEachMap[K comparable, V any](forEach ForEachMapFunc[K, V], enum func(K, V)) {
    98  	forEach(enum)
    99  }
   100  
   101  // Map is a function type wrapper for naked maps.
   102  // Map result can be passed as a first argument to `ForEachMap`, `FindFirstMap` and `FindFirstMapError` routines
   103  func Map[K comparable, V any](m map[K]V) ForEachMapFunc[K, V] {
   104  	return func(enum func(K, V)) {
   105  		for k, v := range m {
   106  			enum(k, v)
   107  		}
   108  	}
   109  }
   110  
   111  // FindFirstMap find first key-value pair by `forEach` iterator, using test function.
   112  func FindFirstMap[K comparable, V any](forEach ForEachMapFunc[K, V], test func(K, V) bool) (ok bool, key K, value V) {
   113  	forEach(func(k K, v V) {
   114  		if ok {
   115  			return
   116  		}
   117  		if ok = test(k, v); ok {
   118  			key = k
   119  			value = v
   120  		}
   121  	})
   122  	return ok, key, value
   123  }
   124  
   125  // FindFirstMapKey find first key-value pair by `forEach` iterator, using specified `key` value.
   126  func FindFirstMapKey[K comparable, V any](forEach ForEachMapFunc[K, V], key K) (ok bool, foundedKey K, value V) {
   127  	forEach(func(k K, v V) {
   128  		if ok {
   129  			return
   130  		}
   131  		if ok = (k == key); ok {
   132  			foundedKey = k
   133  			value = v
   134  		}
   135  	})
   136  	return ok, foundedKey, value
   137  }
   138  
   139  // FindFirstError find first key-value pair with error by `forEach` iterator, using test function.
   140  func FindFirstMapError[K comparable, V any](forEach ForEachMapFunc[K, V], test func(K, V) error) (key K, value V, err error) {
   141  	forEach(func(k K, v V) {
   142  		if err != nil {
   143  			return
   144  		}
   145  		if err = test(k, v); err != nil {
   146  			key = k
   147  			value = v
   148  		}
   149  	})
   150  	return key, value, err
   151  }