From 9835c0d7a7f2133fb38000ccf35ee4a1d32d73c7 Mon Sep 17 00:00:00 2001 From: CHEN Feng Date: Sun, 11 Sep 2022 01:05:15 +0800 Subject: [PATCH] Add CopyTo and change behavior of TransformTo (#103) --- README.md | 3 +- README_zh.md | 1 + generated_doc.md | 137 ++++++++++++++++++++++++---------------------- stack.go | 32 +++++------ transform.go | 26 +++++---- transform_test.go | 20 +++++-- vector.go | 3 + 7 files changed, 126 insertions(+), 96 deletions(-) diff --git a/README.md b/README.md index d2336be..3b0aff4 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ There are following container interfaces: Different interface has different methods. The `Container` interface has following methods: -- `IsEmpty() bool` Returns whether the container is empty +- `IsEmpty() bool` returns whether the container is empty - `Len() int` returns the number of elements in the container - `Clear()` to clear the container @@ -186,6 +186,7 @@ indicating that a custom comparison function can be passed. #### Data manipulation - `Copy` return a copies of specified slice +- `CopyTo` copies all elements in slice a to slice to, return the copied slice. - `Fill` repeatedly fills a slice with the specified value - `FillPattern` repeatedly fills a slice with the specified pattern - `Replace` replaces every element that equals to old with new diff --git a/README_zh.md b/README_zh.md index eec975e..7583661 100644 --- a/README_zh.md +++ b/README_zh.md @@ -168,6 +168,7 @@ func TestSkipList_ForEachMutable(t *testing.T) { #### 数据操作 - `Copy` 返回切片的拷贝 +- `CopyTo` 拷贝切片的内容到另一个切片 - `Fill` 用指定的值重复填充一个切片 - `FillPattern` 用指定的模式重复填充一个切片 - `Replace` 替换所有等于指定值的元素为新值 diff --git a/generated_doc.md b/generated_doc.md index f4df888..4453b0e 100755 --- a/generated_doc.md +++ b/generated_doc.md @@ -21,6 +21,7 @@ Package stl4go is a generic container and algorithm library for go. - [func BinarySearchFunc[T any](a []T, value T, less LessFn[T]) (index int, ok bool)](<#func-binarysearchfunc>) - [func Compare[E Ordered](a, b []E) int](<#func-compare>) - [func Copy[T any](a []T) []T](<#func-copy>) +- [func CopyTo[T any](a []T, to []T) []T](<#func-copyto>) - [func Count[T comparable](a []T, x T) int](<#func-count>) - [func CountIf[T comparable](a []T, pred func(T) bool) int](<#func-countif>) - [func DescSort[T Ordered](a []T)](<#func-descsort>) @@ -201,13 +202,13 @@ Package stl4go is a generic container and algorithm library for go. - [type Stack](<#type-stack>) - [func NewStack[T any]() *Stack[T]](<#func-newstack>) - [func NewStackCap[T any](capicity int) *Stack[T]](<#func-newstackcap>) - - [func (s *Stack[T]) Cap() int](<#func-stackt-cap>) + - [func (s Stack[T]) Cap() int](<#func-stackt-cap>) - [func (s *Stack[T]) Clear()](<#func-stackt-clear>) - - [func (s *Stack[T]) IsEmpty() bool](<#func-stackt-isempty>) - - [func (s *Stack[T]) Len() int](<#func-stackt-len>) + - [func (s Stack[T]) IsEmpty() bool](<#func-stackt-isempty>) + - [func (s Stack[T]) Len() int](<#func-stackt-len>) - [func (s *Stack[T]) Pop() T](<#func-stackt-pop>) - [func (s *Stack[T]) Push(t T)](<#func-stackt-push>) - - [func (s *Stack[T]) Top() T](<#func-stackt-top>) + - [func (s Stack[T]) Top() T](<#func-stackt-top>) - [func (s *Stack[T]) TryPop() (val T, ok bool)](<#func-stackt-trypop>) - [type Unsigned](<#type-unsigned>) - [type Vector](<#type-vector>) @@ -320,6 +321,16 @@ Copy make a copy of slice a. Complexity: O\(len\(a\)\). +## func [CopyTo]() + +```go +func CopyTo[T any](a []T, to []T) []T +``` + +CopyTo copies all elements in slice a to slice to, return the copied slice. if slice to is large enough, no memory allocation occurs. + +Complexity: O\(len\(a\)\). + ## func [Count]() ```go @@ -370,7 +381,7 @@ Equal returns whether two slices are equal. Return true if they are the same len Complexity: O\(min\(len\(a\), len\(b\)\)\). -## func [Fill]() +## func [Fill]() ```go func Fill[T any](a []T, v T) @@ -380,7 +391,7 @@ Fill fills each element in slice a with new value v. Complexity: O\(len\(a\)\). -## func [FillPattern]() +## func [FillPattern]() ```go func FillPattern[T any](a []T, pattern []T) @@ -658,7 +669,7 @@ Range make a \[\]T filled with values in the \`\[first, last\)\` sequence. NOTE: Complexity: O\(last\-first\). -## func [Remove]() +## func [Remove]() ```go func Remove[T comparable](a []T, x T) []T @@ -668,7 +679,7 @@ Remove remove the elements which equals to x from the input slice. return the pr Complexity: O\(len\(a\)\). -## func [RemoveCopy]() +## func [RemoveCopy]() ```go func RemoveCopy[T comparable](a []T, x T) []T @@ -688,7 +699,7 @@ RemoveHeapFunc removes and returns the element at index i from the heap. Complexity: is O\(log\(n\)\) where n = len\(\*heap\). -## func [RemoveIf]() +## func [RemoveIf]() ```go func RemoveIf[T any](a []T, cond func(T) bool) []T @@ -698,7 +709,7 @@ RemoveIf remove each element which make cond\(x\) returns true from the input sl Complexity: O\(len\(a\)\). -## func [RemoveIfCopy]() +## func [RemoveIfCopy]() ```go func RemoveIfCopy[T any](a []T, cond func(T) bool) []T @@ -718,7 +729,7 @@ RemoveMinHeap removes and returns the element at index i from the min heap. Complexity: is O\(log\(n\)\) where n = len\(\*heap\). -## func [Replace]() +## func [Replace]() ```go func Replace[T comparable](a []T, old, new T) @@ -728,7 +739,7 @@ Replace replaces every element that equals to old with new. Complexity: O\(len\(a\)\). -## func [ReplaceIf]() +## func [ReplaceIf]() ```go func ReplaceIf[T any](a []T, pred func(v T) bool, new T) @@ -738,7 +749,7 @@ ReplaceIf replaces every element that make preq returns true with new. Complexity: O\(len\(a\)\). -## func [Reverse]() +## func [Reverse]() ```go func Reverse[T any](a []T) @@ -748,7 +759,7 @@ Reverse reverses the order of the elements in the slice a. Complexity: O\(len\(a\)\). -## func [ReverseCopy]() +## func [ReverseCopy]() ```go func ReverseCopy[T any](a []T) []T @@ -758,7 +769,7 @@ ReverseCopy returns a reversed copy of slice a. Complexity: O\(len\(a\)\). -## func [Shuffle]() +## func [Shuffle]() ```go func Shuffle[T any](a []T) @@ -824,7 +835,7 @@ func SumAs[R, T Numeric](a []T) R SumAs summarize all elements in a. returns the result as type R, this is useful when T is too small to hold the result. Complexity: O\(len\(a\)\). -## func [Transform]() +## func [Transform]() ```go func Transform[T any](a []T, op func(T) T) @@ -834,7 +845,7 @@ Transform applies the function op to each element in slice a and set it back to Complexity: O\(len\(a\)\). -## func [TransformCopy]() +## func [TransformCopy]() ```go func TransformCopy[R any, T any](a []T, op func(T) R) []R @@ -844,19 +855,17 @@ TransformCopy applies the function op to each element in slice a and return all Complexity: O\(len\(a\)\). -## func [TransformTo]() +## func [TransformTo]() ```go func TransformTo[R any, T any](a []T, op func(T) R, b []R) []R ``` -TransformTo applies the function op to each element in slice a and fill it to slice b. - -The len\(b\) must not lesser than len\(a\). +TransformTo applies the function op to each element in slice a and fill it to slice b, return the transformed slice. If cap\(b\) \>= len\(a\), no memory allocation. Complexity: O\(len\(a\)\). -## func [Unique]() +## func [Unique]() ```go func Unique[T comparable](a []T) []T @@ -866,7 +875,7 @@ Unique remove adjacent repeated elements from the input slice. return the proces Complexity: O\(len\(a\)\). -## func [UniqueCopy]() +## func [UniqueCopy]() ```go func UniqueCopy[T comparable](a []T) []T @@ -928,7 +937,7 @@ Clear implements the Container interface. func (s BuiltinSet[K]) Delete(k K) ``` -Delete deletes a element in the set. It returns nothing, so it's faster than Remove. +Delete deletes an element from the set. It returns nothing, so it's faster than Remove. ### func \(BuiltinSet\[K\]\) [Difference]() @@ -1136,7 +1145,7 @@ func (l *DList[T]) ForEach(cb func(val T)) ForEach iterate the list, apply each element to the cb callback function. -### func \(\*DList\[T\]\) [ForEachIf]() +### func \(\*DList\[T\]\) [ForEachIf]() ```go func (l *DList[T]) ForEachIf(cb func(val T) bool) @@ -1144,7 +1153,7 @@ func (l *DList[T]) ForEachIf(cb func(val T) bool) ForEachIf iterate the list, apply each element to the cb callback function, stop if cb returns false. -### func \(\*DList\[T\]\) [ForEachMutable]() +### func \(\*DList\[T\]\) [ForEachMutable]() ```go func (l *DList[T]) ForEachMutable(cb func(val *T)) @@ -1152,7 +1161,7 @@ func (l *DList[T]) ForEachMutable(cb func(val *T)) ForEachMutable iterate the list, apply pointer of each element to the cb callback function. -### func \(\*DList\[T\]\) [ForEachMutableIf]() +### func \(\*DList\[T\]\) [ForEachMutableIf]() ```go func (l *DList[T]) ForEachMutableIf(cb func(val *T) bool) @@ -1578,7 +1587,7 @@ NewPriorityQueueOn creates a new priority object on the specified slices. The sl func (pq *PriorityQueue[T]) Clear() ``` -Clear checks whether priority queue has no elements. +Clear clear the priority queue. ### func \(\*PriorityQueue\[T\]\) [IsEmpty]() @@ -1982,10 +1991,10 @@ func NewStackCap[T any](capicity int) *Stack[T] NewStackCap creates a new Stack object with the specified capicity. -### func \(\*Stack\[T\]\) [Cap]() +### func \(Stack\[T\]\) [Cap]() ```go -func (s *Stack[T]) Cap() int +func (s Stack[T]) Cap() int ``` Cap returns the capacity of the stack. @@ -1998,18 +2007,18 @@ func (s *Stack[T]) Clear() Clear implements the Container interface. -### func \(\*Stack\[T\]\) [IsEmpty]() +### func \(Stack\[T\]\) [IsEmpty]() ```go -func (s *Stack[T]) IsEmpty() bool +func (s Stack[T]) IsEmpty() bool ``` IsEmpty implements the Container interface. -### func \(\*Stack\[T\]\) [Len]() +### func \(Stack\[T\]\) [Len]() ```go -func (s *Stack[T]) Len() int +func (s Stack[T]) Len() int ``` Len implements the Container interface. @@ -2030,10 +2039,10 @@ func (s *Stack[T]) Push(t T) Push pushes the element to the top of the stack. -### func \(\*Stack\[T\]\) [Top]() +### func \(Stack\[T\]\) [Top]() ```go -func (s *Stack[T]) Top() T +func (s Stack[T]) Top() T ``` Top returns the top element in the stack. It must be called when s.IsEmpty\(\) returned false, otherwise it will panic. @@ -2056,7 +2065,7 @@ type Unsigned interface { } ``` -## type [Vector]() +## type [Vector]() Vector is a sequence container representing array that can change in size. @@ -2064,7 +2073,7 @@ Vector is a sequence container representing array that can change in size. type Vector[T any] []T ``` -### func [AsVector]() +### func [AsVector]() ```go func AsVector[T any](s []T) Vector[T] @@ -2072,7 +2081,7 @@ func AsVector[T any](s []T) Vector[T] AsVector casts a slice as a Vector object. -### func [MakeVector]() +### func [MakeVector]() ```go func MakeVector[T any]() Vector[T] @@ -2080,7 +2089,7 @@ func MakeVector[T any]() Vector[T] MakeVector creates an empty Vector object. -### func [MakeVectorCap]() +### func [MakeVectorCap]() ```go func MakeVectorCap[T any](c int) Vector[T] @@ -2088,7 +2097,7 @@ func MakeVectorCap[T any](c int) Vector[T] MakeVectorCap creates an empty Vector object with specified capacity. -### func [VectorOf]() +### func [VectorOf]() ```go func VectorOf[T any](v ...T) Vector[T] @@ -2096,7 +2105,7 @@ func VectorOf[T any](v ...T) Vector[T] VectorOf creates a Vector object with initial values. -### func \(\*Vector\[T\]\) [Append]() +### func \(\*Vector\[T\]\) [Append]() ```go func (v *Vector[T]) Append(x ...T) @@ -2104,7 +2113,7 @@ func (v *Vector[T]) Append(x ...T) Append appends the values x... to the tail of the vector. -### func \(\*Vector\[T\]\) [At]() +### func \(\*Vector\[T\]\) [At]() ```go func (v *Vector[T]) At(i int) T @@ -2112,7 +2121,7 @@ func (v *Vector[T]) At(i int) T At returns the element value at the index i. You can also use the \[\] operator, and it's better. -### func \(Vector\[T\]\) [Back]() +### func \(Vector\[T\]\) [Back]() ```go func (v Vector[T]) Back() T @@ -2120,7 +2129,7 @@ func (v Vector[T]) Back() T Back returns the element at the end of the vector. It must be called when IsEmpty\(\) returned false, otherwise it will panic. -### func \(\*Vector\[T\]\) [Cap]() +### func \(\*Vector\[T\]\) [Cap]() ```go func (v *Vector[T]) Cap() int @@ -2128,7 +2137,7 @@ func (v *Vector[T]) Cap() int Cap returns the capacity of the vector. -### func \(\*Vector\[T\]\) [Clear]() +### func \(\*Vector\[T\]\) [Clear]() ```go func (v *Vector[T]) Clear() @@ -2136,7 +2145,7 @@ func (v *Vector[T]) Clear() Clear erases all elements from the vector. After this call, Len\(\) returns zero. Leaves the Cap\(\) of the vector unchanged. -### func \(Vector\[T\]\) [ForEach]() +### func \(Vector\[T\]\) [ForEach]() ```go func (v Vector[T]) ForEach(cb func(val T)) @@ -2144,7 +2153,7 @@ func (v Vector[T]) ForEach(cb func(val T)) ForEach iterate the container, apply each element to the cb callback function. -### func \(Vector\[T\]\) [ForEachIf]() +### func \(Vector\[T\]\) [ForEachIf]() ```go func (v Vector[T]) ForEachIf(cb func(val T) bool) @@ -2152,7 +2161,7 @@ func (v Vector[T]) ForEachIf(cb func(val T) bool) ForEachIf iterate the container, apply each element to the cb callback function, stop if cb returns false. -### func \(Vector\[T\]\) [ForEachMutable]() +### func \(Vector\[T\]\) [ForEachMutable]() ```go func (v Vector[T]) ForEachMutable(cb func(val *T)) @@ -2160,7 +2169,7 @@ func (v Vector[T]) ForEachMutable(cb func(val *T)) ForEachMutable iterate the container, apply pointer of each element to the cb callback function. -### func \(Vector\[T\]\) [ForEachMutableIf]() +### func \(Vector\[T\]\) [ForEachMutableIf]() ```go func (v Vector[T]) ForEachMutableIf(cb func(val *T) bool) @@ -2168,7 +2177,7 @@ func (v Vector[T]) ForEachMutableIf(cb func(val *T) bool) ForEachMutableIf iterate the container, apply pointer of each element to the cb callback function, stop if cb returns false. -### func \(\*Vector\[T\]\) [Insert]() +### func \(\*Vector\[T\]\) [Insert]() ```go func (v *Vector[T]) Insert(i int, x ...T) @@ -2178,7 +2187,7 @@ Insert inserts the values x... into the vector at index i. After the insertion, Complexity: O\(len\(s\) \+ len\(v\)\). -### func \(\*Vector\[T\]\) [IsEmpty]() +### func \(\*Vector\[T\]\) [IsEmpty]() ```go func (v *Vector[T]) IsEmpty() bool @@ -2186,7 +2195,7 @@ func (v *Vector[T]) IsEmpty() bool IsEmpty implements the Container interface. -### func \(Vector\[T\]\) [Iterate]() +### func \(Vector\[T\]\) [Iterate]() ```go func (v Vector[T]) Iterate() MutableIterator[T] @@ -2194,7 +2203,7 @@ func (v Vector[T]) Iterate() MutableIterator[T] Iterate returns an iterator to the whole container. -### func \(Vector\[T\]\) [IterateRange]() +### func \(Vector\[T\]\) [IterateRange]() ```go func (v Vector[T]) IterateRange(i, j int) MutableIterator[T] @@ -2202,7 +2211,7 @@ func (v Vector[T]) IterateRange(i, j int) MutableIterator[T] IterateRange returns an iterator to the range \[i, j\) of the container. -### func \(\*Vector\[T\]\) [Len]() +### func \(\*Vector\[T\]\) [Len]() ```go func (v *Vector[T]) Len() int @@ -2210,7 +2219,7 @@ func (v *Vector[T]) Len() int Len implements the Container interface. -### func \(\*Vector\[T\]\) [PopBack]() +### func \(\*Vector\[T\]\) [PopBack]() ```go func (v *Vector[T]) PopBack() T @@ -2218,7 +2227,7 @@ func (v *Vector[T]) PopBack() T PopBack popups an element from the end of the vector. It must be called when IsEmpty\(\) returned false, otherwise it will panic. -### func \(\*Vector\[T\]\) [PushBack]() +### func \(\*Vector\[T\]\) [PushBack]() ```go func (v *Vector[T]) PushBack(x T) @@ -2228,7 +2237,7 @@ PushBack pushs an element to the end of the vector. Complexity: O\(1\) if v.Len\(\) \< v.Cap\(\), therwise O\(len\(v\)\). -### func \(\*Vector\[T\]\) [Remove]() +### func \(\*Vector\[T\]\) [Remove]() ```go func (v *Vector[T]) Remove(i int) @@ -2238,7 +2247,7 @@ Remove removes 1 element in the vector. Complexity: O\(len\(s\) \- i\). -### func \(\*Vector\[T\]\) [RemoveLength]() +### func \(\*Vector\[T\]\) [RemoveLength]() ```go func (v *Vector[T]) RemoveLength(i int, len int) @@ -2246,7 +2255,7 @@ func (v *Vector[T]) RemoveLength(i int, len int) RemoveLength removes the elements in the range\[i, i\+len\) from the vector. -### func \(\*Vector\[T\]\) [RemoveRange]() +### func \(\*Vector\[T\]\) [RemoveRange]() ```go func (v *Vector[T]) RemoveRange(i, j int) @@ -2254,7 +2263,7 @@ func (v *Vector[T]) RemoveRange(i, j int) RemoveRange removes the elements in the range\[i, j\) from the vector. -### func \(\*Vector\[T\]\) [Reserve]() +### func \(\*Vector\[T\]\) [Reserve]() ```go func (v *Vector[T]) Reserve(l int) @@ -2264,7 +2273,7 @@ Reserve increases the capacity of the vector \(the total number of elements that Reserve\(\) does not change the size of the vector. -### func \(\*Vector\[T\]\) [Set]() +### func \(\*Vector\[T\]\) [Set]() ```go func (v *Vector[T]) Set(i int, x T) @@ -2272,7 +2281,7 @@ func (v *Vector[T]) Set(i int, x T) Set sets the value of the element at the index i. You can also use the \[\] operator, and it's better. -### func \(\*Vector\[T\]\) [Shrink]() +### func \(\*Vector\[T\]\) [Shrink]() ```go func (v *Vector[T]) Shrink() @@ -2280,7 +2289,7 @@ func (v *Vector[T]) Shrink() Shrink removes unused capacity from the vector. -### func \(\*Vector\[T\]\) [TryPopBack]() +### func \(\*Vector\[T\]\) [TryPopBack]() ```go func (v *Vector[T]) TryPopBack() (T, bool) diff --git a/stack.go b/stack.go index 408d16f..274a83f 100644 --- a/stack.go +++ b/stack.go @@ -3,7 +3,7 @@ package stl4go // Stack s is a container adaptor that provides the functionality of a stack, // a LIFO (last-in, first-out) data structure. type Stack[T any] struct { - ele []T + elements []T } // NewStack creates a new Stack object. @@ -17,38 +17,38 @@ func NewStackCap[T any](capicity int) *Stack[T] { } // IsEmpty implements the Container interface. -func (s *Stack[T]) IsEmpty() bool { - return len(s.ele) == 0 +func (s Stack[T]) IsEmpty() bool { + return len(s.elements) == 0 } // Len implements the Container interface. -func (s *Stack[T]) Len() int { - return len(s.ele) +func (s Stack[T]) Len() int { + return len(s.elements) } // Cap returns the capacity of the stack. -func (s *Stack[T]) Cap() int { - return cap(s.ele) +func (s Stack[T]) Cap() int { + return cap(s.elements) } // Clear implements the Container interface. func (s *Stack[T]) Clear() { - s.ele = s.ele[0:0] + s.elements = s.elements[0:0] } // Push pushes the element to the top of the stack. func (s *Stack[T]) Push(t T) { - s.ele = append(s.ele, t) + s.elements = append(s.elements, t) } // TryPop tries to popup an element from the top of the stack. func (s *Stack[T]) TryPop() (val T, ok bool) { var t T - if len(s.ele) == 0 { + if len(s.elements) == 0 { return t, false } - t = s.ele[len(s.ele)-1] - s.ele = s.ele[:len(s.ele)-1] + t = s.elements[len(s.elements)-1] + s.elements = s.elements[:len(s.elements)-1] return t, true } @@ -56,14 +56,14 @@ func (s *Stack[T]) TryPop() (val T, ok bool) { // It must be called when IsEmpty() returned false, // otherwise it will panic. func (s *Stack[T]) Pop() T { - t := s.ele[len(s.ele)-1] - s.ele = s.ele[:len(s.ele)-1] + t := s.elements[len(s.elements)-1] + s.elements = s.elements[:len(s.elements)-1] return t } // Top returns the top element in the stack. // It must be called when s.IsEmpty() returned false, // otherwise it will panic. -func (s *Stack[T]) Top() T { - return s.ele[len(s.ele)-1] +func (s Stack[T]) Top() T { + return s.elements[len(s.elements)-1] } diff --git a/transform.go b/transform.go index 5daf4a9..9123527 100644 --- a/transform.go +++ b/transform.go @@ -6,7 +6,15 @@ import "math/rand" // // Complexity: O(len(a)). func Copy[T any](a []T) []T { - b := append([]T{}, a...) + return append([]T{}, a...) +} + +// CopyTo copies all elements in slice a to slice to, return the copied slice. +// if slice to is large enough, no memory allocation occurs. +// +// Complexity: O(len(a)). +func CopyTo[T any](a []T, to []T) []T { + b := append(to[0:0], a...) return b } @@ -44,19 +52,17 @@ func FillPattern[T any](a []T, pattern []T) { } } -// TransformTo applies the function op to each element in slice a and fill it to slice b. -// -// The len(b) must not lesser than len(a). +// TransformTo applies the function op to each element in slice a and fill it to slice b, +// return the transformed slice. +// If cap(b) >= len(a), no memory allocation. // // Complexity: O(len(a)). func TransformTo[R any, T any](a []T, op func(T) R, b []R) []R { - if len(b) < len(a) { - panic("TransformTo: len(b) < len(a)") - } - for i, v := range a { - b[i] = op(v) + b = b[0:0] + for i := range a { + b = append(b, op(a[i])) } - return b[:len(a)] + return b } // Transform applies the function op to each element in slice a and set it back to the same place in a. diff --git a/transform_test.go b/transform_test.go index 35850e7..a9eaf14 100644 --- a/transform_test.go +++ b/transform_test.go @@ -15,6 +15,15 @@ func Test_Copy(t *testing.T) { expectTrue(t, Equal(a, b)) } +func Test_CopyTo(t *testing.T) { + a := []int{1, 2, 3, 4} + tos := [][]int{nil, make([]int, 0), make([]int, 10)} + for _, to := range tos { + b := CopyTo(a, to) + expectTrue(t, Equal(a, b)) + } +} + func Test_Fill(t *testing.T) { a := []int{1, 2, 3, 4} Fill(a, 1) @@ -63,14 +72,15 @@ func Test_Transform(t *testing.T) { func Test_TransformTo(t *testing.T) { a := Range(0, 100) b := make([]string, len(a)) - TransformTo(a, func(v int) string { return strconv.Itoa(v) }, b) + r1 := TransformTo(a, func(v int) string { return strconv.Itoa(v) }, b) for i, v := range a { expectEq(t, b[i], strconv.Itoa(v)) } - expectPanic(t, func() { - c := make([]string, len(a)-1) - TransformTo(a, func(v int) string { return strconv.Itoa(v) }, c) - }) + expectEq(t, &r1[0], &b[0]) + c := make([]string, len(a)-1) + r2 := TransformTo(a, func(v int) string { return strconv.Itoa(v) }, c) + expectEq(t, len(a), len(r2)) + expectNe(t, &r2[0], &c[0]) } func Test_TransformCopy(t *testing.T) { diff --git a/vector.go b/vector.go index d21d27f..ac9d30a 100644 --- a/vector.go +++ b/vector.go @@ -1,5 +1,8 @@ package stl4go +// Many tricks are from: +// https://github.com/golang/go/wiki/SliceTricks#in-place-deduplicate-comparable + // Vector is a sequence container representing array that can change in size. type Vector[T any] []T