github.com/primecitizens/pcz/std@v0.2.1/core/iter/slice.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  
     4  package iter
     5  
     6  func SliceNth[Elem any](s []Elem, i int) (elem Elem, ok bool) {
     7  	i, ok = Index(i, len(s))
     8  	if ok {
     9  		return s[i], true
    10  	}
    11  
    12  	return
    13  }
    14  
    15  // Slice returns an iterator for the given slice.
    16  func Slice[Elem any](x []Elem) SliceIter[Elem] {
    17  	return SliceIter[Elem](x)
    18  }
    19  
    20  type SliceIter[Elem any] []Elem
    21  
    22  // Nth implements Core[T]
    23  func (s SliceIter[E]) Nth(i int) (elem E, ok bool) {
    24  	i, ok = Index(i, len(s))
    25  	if ok {
    26  		return s[i], true
    27  	}
    28  
    29  	return
    30  }
    31  
    32  // Len implements Finite.
    33  func (s SliceIter[E]) Len() int { return len(s) }
    34  
    35  // SliceFrom implements Divisible[SliceIter[E]]
    36  func (s SliceIter[E]) SliceFrom(start int) SliceIter[E] {
    37  	start, ok := Bound(start, len(s))
    38  	if ok {
    39  		return s[start:]
    40  	}
    41  
    42  	return nil
    43  }
    44  
    45  type SliceIterEx[Elem any, T []Elem] int
    46  
    47  func (x SliceIterEx[Elem, T]) NthEx(s T, i int) (e Elem, ok bool) {
    48  	if int(x) >= len(s) || x < 0 {
    49  		return
    50  	}
    51  
    52  	i, ok = Index(i, len(s))
    53  	if ok {
    54  		return s[i], true
    55  	}
    56  
    57  	return
    58  }
    59  
    60  func (x SliceIterEx[Elem, T]) LenEx(s T) int {
    61  	if int(x) >= len(s) || x < 0 {
    62  		return 0
    63  	}
    64  
    65  	return len(s) - int(x)
    66  }
    67  
    68  func (x SliceIterEx[Elem, T]) SliceFromEx(s T, start int) SliceIterEx[Elem, T] {
    69  	start, ok := Bound(start, x.LenEx(s))
    70  	if ok {
    71  		return x + SliceIterEx[Elem, T](start)
    72  	}
    73  
    74  	return SliceIterEx[Elem, T](len(s))
    75  }
    76  
    77  func SliceReverse[Elem any](x []Elem) SliceReverseIter[Elem] {
    78  	return SliceReverseIter[Elem](x)
    79  }
    80  
    81  type SliceReverseIter[Elem any] []Elem
    82  
    83  // Nth implements Core[T]
    84  func (s SliceReverseIter[E]) Nth(i int) (elem E, ok bool) {
    85  	if i < 0 {
    86  		i = -i - 1
    87  		ok = /* implicitly true: i >= 0 && */ i < len(s)
    88  	} else {
    89  		i = len(s) - i - 1
    90  		ok = i >= 0 && i < len(s)
    91  	}
    92  
    93  	if ok {
    94  		return s[i], true
    95  	}
    96  
    97  	return
    98  }
    99  
   100  // Len implements Finite.
   101  func (s SliceReverseIter[E]) Len() int { return len(s) }
   102  
   103  // SliceFrom implements Divisible[SliceReverseIter[E]]
   104  func (s SliceReverseIter[E]) SliceFrom(start int) SliceReverseIter[E] {
   105  	if start < 0 {
   106  		start = len(s) + start + 1
   107  	} else {
   108  		start = len(s) - start
   109  	}
   110  
   111  	if start >= 0 && start <= len(s) {
   112  		return s[:start]
   113  	}
   114  
   115  	return nil
   116  }
   117  
   118  type SliceReverseIterEx[Elem any, T []Elem] int
   119  
   120  // Nth implements Core[T]
   121  func (x SliceReverseIterEx[Elem, T]) NthEx(s T, i int) (e Elem, ok bool) {
   122  	if i < 0 {
   123  		i = -i - 1
   124  		ok = /* implicitly true: i >= 0 && */ i < len(s)
   125  	} else {
   126  		i = len(s) - i - 1
   127  		ok = i >= 0 && i < len(s)
   128  	}
   129  
   130  	if ok {
   131  		return s[i], true
   132  	}
   133  
   134  	return
   135  }
   136  
   137  // Len implements Finite.
   138  func (x SliceReverseIterEx[Elem, T]) LenEx(s T) int { return len(s) }
   139  
   140  // // SliceFrom implements Divisible[SliceReverseIterEx[Elem, T]]
   141  // func (x SliceReverseIterEx[Elem, T]) SliceFromEx(s T, start int) SliceReverseIterEx[Elem, T] {
   142  // 	if start < 0 {
   143  // 		start = len(s) + start + 1
   144  // 	} else {
   145  // 		start = len(s) - start
   146  // 	}
   147  //
   148  // 	if start >= 0 && start <= len(s) {
   149  // 		return s[:start]
   150  // 	}
   151  //
   152  // 	return nil
   153  // }