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 // }