From ef9c29f1fb02527e6a207c16d896b9a7b9be5f5f Mon Sep 17 00:00:00 2001 From: Linneeeeeeee Date: Mon, 23 Oct 2023 12:21:07 +1100 Subject: [PATCH] Dev (#49) * Dev --- README.md | 460 +++++++++++++++++++++++++++++++----------------------- slice.go | 417 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 633 insertions(+), 244 deletions(-) diff --git a/README.md b/README.md index afbc2fe..57b8570 100644 --- a/README.md +++ b/README.md @@ -45,530 +45,592 @@ Provided methods for `&slice.Slice[T]`. ### Append Appends values to the end of the slice and returns a pointer to the modified slice. ```Go -s := &slice.Slice[int]{1, 2, 3} -s.Append(4, 5) // s is now [1, 2, 3, 4, 5]. +newSlice := &slice.Slice[int]{} +newSlice.Append(1, 2) +fmt.Println(newSlice) // &[1, 2] ``` ### AppendFunc Appends selected elements to the end of the slice based on a provided condition. ```Go -s := &slice.Slice[int]{} -s.AppendFunc([]int{1, 2, 3, 4, 5}, func(i int, value int) bool { - return value%2 == 0 // Append even numbers to the Slice. +newSlice := &slice.Slice[int]{} +values := []int{1, 2, 3, 4, 5} +newSlice.AppendFunc(values, func(i int, value int) bool { + return value%2 == 0 }) +fmt.Println(newSlice) // &[2, 4] ``` ### AppendLength Appends values to the end of the slice and returns the length of the modified slice. ```Go -s := &slice.Slice[int]{1, 2, 3} -length := s.AppendLength(4, 5) // s is now [1, 2, 3, 4, 5], length is 5. +newSlice := &slice.Slice[int]{} +length := newSlice.AppendLength(1, 2, 3) +fmt.Println(length) // 3 ``` ### Bounds Checks if an index is within the valid range of indices for the slice. ```Go -s := &slice.Slice[int]{1, 2, 3} -inBounds := s.Bounds(1) // inBounds is true. -outOfBounds := s.Bounds(5) // outOfBounds is false. +newSlice := &slice.Slice[int]{1, 2, 3} +isWithinBounds := newSlice.Bounds(2) +fmt.Println(isWithinBounds) // true ``` ### Clone Creates a duplicate of the current slice with a reference to a new pointer. ```Go -s1 := &slice.Slice[int]{1, 2} -s2 := s1.Clone() -s2.Replace(0, 3) // s1 is still [1, 2], s2 is [3, 2]. +newSlice := &slice.Slice[int]{1, 2, 3} +cloneSlice := newSlice.Clone() +fmt.Println(cloneSlice) // &[1, 2, 3] ``` ### Concatenate Merges elements from another slice to the tail of the receiver slice. ```Go -s1 := &slice.Slice[int]{1, 2, 3} -s2 := &slice.Slice[int]{4, 5} -s1.Concatenate(s2) // s1 is now [1, 2, 3, 4, 5]. +slice1 := &slice.Slice[int]{1, 2} +slice2 := &slice.Slice[int]{3, 4} +slice1.Concatenate(slice2) +fmt.Println(newSlice) // &[1, 2, 3, 4] ``` ### ConcatenateFunc Appends elements from another slice based on a filtering function. ```Go -s1 := &slice.Slice[int]{1, 2, 3} -s2 := &slice.Slice[int]{4, 5, 6} -s1.ConcatenateFunc(s2, func(i int, value int) bool { - return value%2 == 0 -}) // s1 is now [1, 2, 3, 4, 6]. +slice1 := &slice.Slice[int]{1, 2, 3} +slice2 := &slice.Slice[int]{4, 5, 6} +slice1.ConcatenateFunc(slice2, func(i int, value int) bool { + return value%2 == 0 +}) +fmt.Println(slice1) // &[2, 4, 6] ``` ### ConcatenateLength Merges elements from another slice to the tail of the receiver slice and returns the length of the modified slice. ```Go -s1 := &slice.Slice[int]{1, 2, 3} -s2 := &slice.Slice[int]{4, 5} -length := s1.ConcatenateLength(s2) // s1 is now [1, 2, 3, 4, 5], length is 5. +slice1 := &slice.Slice[int]{1, 2} +slice2 := &slice.Slice[int]{3, 4} +length := slice1.ConcatenateLength(slice2) +fmt.Println(length) // 4 ``` ### Contains Checks if a value exists in the slice. ```Go -s := &slice.Slice[string]{"apple", "banana", "cherry"} -containsBanana := s.Contains("banana") // containsBanana is true. +newSlice := &slice.Slice[int]{1, 2, 3} +contains := slice.Contains(2) +fmt.Println(contains) // true ``` ### ContainsMany Checks if multiple values exist in the slice and returns a boolean slice indicating their presence. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -result := s.ContainsMany(2, 4, 6) // result will be [true, true, false]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +contains := slice.ContainsMany(2, 6) +fmt.Println(contains) // &[true, false] +``` + +### Deduplicate +Removes values from the slice that have the same basic hash value. +```Go +newSlice := &slice.Slice[int]{1, 2, 2, 3, 4, 4, 5} +slice.Deduplicate() +fmt.Println(newSlice) // &[1, 2, 3, 4, 5] ``` ### Delete Safely removes an element from the slice by index. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -s.Delete(2) // s is now [1, 2, 4, 5]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +newSlice := slice.Delete(2) +fmt.Println(newSlice) // &[1, 2, 4, 5] ``` ### DeleteFunc Safely removes elements from the slice based on a provided predicate function. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -even := func(i int, value int) bool { return value%2 == 0 } -s.DeleteFunc(even) // 's' will contain [1, 3, 5] after removing even elements. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +newSlice.DeleteFunc(func(i int, value int) bool { + return value%2 == 0 +}) +fmt.Println(newSlice) // &[1, 3, 5] ``` ### DeleteLength Safely removes an element from the slice by index and returns the new length of the modified slice. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -newLength := s.DeleteLength(2) // s is now [1, 2, 4, 5], newLength is 4. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +length := slice.DeleteLength(2) +fmt.Println(length) // 4 ``` ### DeleteOK Safely removes an element from the slice by index and returns a boolean indicating the success of the operation. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -deleted := s.DeleteOK(2) // s is now [1, 2, 4, 5], deleted is true. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +success := slice.DeleteOK(2) +fmt.Println(success) // true ``` ### DeleteUnsafe Removes an element from the slice by index. Panics if index is out of bounds. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -s.DeleteUnsafe(2) -// The slice becomes [1, 2, 4, 5] with the element at index 2 (value 3) removed. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +newSlice.DeleteUnsafe(2) +fmt.Println(newSlice) // &[1, 2, 4, 5] ``` ### Each Executes a provided function for each element in the slice. ```Go -s := &slice.Slice[string]{"apple", "banana", "cherry"} -s.Each(func(i int, value string) { - fmt.Printf("Element %d: %s\n", i, value) // i will be "1", value will be "apple", and so on. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +newSlice.Each(func(i int, value int) { + fmt.Println(value) }) +// Output: +// 1 +// 2 +// 3 +// 4 +// 5 ``` ### EachBreak Executes a provided function for each element in the slice with an optional break condition. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -s.EachBreak(func(i int, value int) bool { - fmt.Printf("Element %d: %d\n", i, value) - return i < 3 // Stop iteration when i is less than 3. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +newSlice.EachBreak(func(i int, value int) bool { + fmt.Println(value) + return value == 3 }) +// Output: +// 1 +// 2 +// 3 ``` ### EachOK Executes a provided function for each element in the slice and returns a bool breaking the loop when true. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -result := slice.EachOK(func(i int, value int) bool { - fmt.Println(i, value) - return value == 4 // Stop iteration at index 3. -}) // result is true. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +allPositive := slice.EachOK(func(i int, value int) bool { + return value > 0 +}) +fmt.Println(allPositive) // true ``` ### EachReverse Executes a provided function for each element in reverse order. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -s.EachReverse(func(i int, value int) { - fmt.Printf("Element %d: %d\n", i, value) // first iteration i will be 4, value will be 5. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +newSlice.EachReverse(func(i int, value int) { + fmt.Println(value) }) +// Output: +// 5 +// 4 +// 3 +// 2 +// 1 ``` ### EachReverseBreak Executes a provided function for each element in reverse order with an optional break condition. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -s.EachReverseBreak(func(i int, value int) bool { - fmt.Printf("Element %d: %d\n", i, value) - return i > 2 // Stop iteration when i is greater than 2. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +newSlice.EachReverseBreak(func(i int, value int) bool { + fmt.Println(value) + return value == 3 }) +// Output: +// 5 +// 4 +// 3 ``` ### EachReverseOK Executes a provided function for each element in the slice and returns a bool breaking the loop when true. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -result := slice.EachReverseOK(func(i int, value int) bool { - fmt.Println(i, value) - return value == 4 // Stop iteration at index 3 (runs two loops). -}) // result is true. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +allPositive := slice.EachReverseOK(func(i int, value int) bool { + return value > 0 +}) +fmt.Println(allPositive) // true ``` ### Equal Checks if the two slices are equal. ```Go -s1 := slice.Slice[int]{1, 2, 3} -s2 := slice.Slice[int]{1, 2, 3} -equal := s1.Equal(s2) // true. +slice1 := &slice.Slice[int]{1, 2, 3} +slice2 := &slice.Slice[int]{1, 2, 3} +isEqual := slice1.Equal(slice2) +fmt.Println(isEqual) // true ``` ### EqualFunc Checks whether the slices are equal based on the filtering function. ```Go -s1 := slice.Slice[int]{1, 2, 3} -s2 := slice.Slice[int]{2, 4, 6} -customEqual := func(i int, value1, value2 int) bool { - return value1*2 == value2 -} -equal := s1.EqualFunc(s2, customEqual) // true. +slice1 := &slice.Slice[int]{1, 2, 3} +slice2 := &slice.Slice[int]{2, 3, 4} +isEqual := slice1.EqualFunc(slice2, func(i int, a int, b int) bool { + return a == b-1 +}) +fmt.Println(isEqual) // true ``` ### EqualLength Checks if the two slices have the same length. ```Go -s1 := slice.Slice[int]{1, 2, 3} -s2 := slice.Slice[int]{2, 4, 6} -equal := s1.Length(s2) // true. +slice1 := &slice.Slice[int]{1, 2, 3} +slice2 := &slice.Slice[int]{4, 5, 6} +isEqualLength := slice1.EqualLength(slice2) +fmt.Println(isEqualLength) // true ``` ### Fetch Retrieves the element at a specified index in the slice. ```Go -s := &slice.Slice[string]{"apple", "banana", "cherry"} -fruit := s.Fetch(1) // fruit will be "banana" +newSlice := &slice.Slice[int]{1, 2, 3} +value := slice.Fetch(1) +fmt.Println(value) // 2 ``` ### FetchLength Retrieves the element at a specified index in the slice and the length of the slice. ```Go -s := &slice.Slice[int]{10, 20, 30, 40, 50} -value, length := s.FetchLength(2) -// value will be 30. -// length will be 5. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +value, length := slice.FetchLength(2) +fmt.Println(value, length) // 3, 5 ``` ### Filter Creates a new slice containing elements that satisfy a given predicate function. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -filtered := s.Filter(func(x int) bool { - return x%2 == 0 Keep only even numbers -}) // filtered will be &Slice[int]{2, 4}. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +filteredSlice := slice.Filter(func(i int, value int) bool { + return value%2 == 0 +}) +fmt.Println(filteredSlice) // &[2, 4] ``` ### FindIndex Finds the index of the first element that satisfies a given predicate function. ```Go -s := &slice.Slice[string]{"apple", "banana", "cherry"} -index, found := s.FindIndex(func(fruit string) bool { - return fruit == "banana" +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +index, found := slice.FindIndex(func(value int) bool { + return value == 3 }) -// index will be 1. -// found will be true. +fmt.Println(index, found) // 2, true ``` ### Get Retrieves the element at a specified index in the slice and returns a boolean indicating success. ```Go -s := &slice.Slice[float64]{3.14, 2.71, 1.61} -value, ok := s.Get(1) -// value will be 2.71. -// ok will be true. +newSlice := &slice.Slice[int]{1, 2, 3} +value, found := slice.Get(1) +fmt.Println(value, found) // 2, true ``` ### GetLength Retrieves the element at a specified index in the slice, a boolean indicating success and the length of the slice. ```Go -s := &slice.Slice[int]{10, 20, 30, 40, 50} -value, ok, length := s.GetLength(2) -// value will be 30. -// ok will be true. -// length will be 5. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +value, found, length := slice.GetLength(2) +fmt.Println(value, found, length) // 3, true, 5 ``` ### IsEmpty Checks if the slice is empty. ```Go -s := &slice.Slice[int]{} -isEmpty := s.IsEmpty() // isEmpty will be true. +newSlice := &slice.Slice[int]{} +isEmpty := newSlice.IsEmpty() +fmt.Println(isEmpty) // true ``` ### IsPopulated Checks if the slice is not empty. ```Go -s := &slice.Slice[int]{10, 20, 30} -isPopulated := s.IsPopulated() // isPopulated will be true. +newSlice := &slice.Slice[int]{1, 2, 3} +isPopulated := newSlice.IsPopulated() +fmt.Println(isPopulated) // true ``` ### Length Returns the number of elements in the slice. ```Go -s := &slice.Slice[int]{10, 20, 30, 40, 50} -length := s.Length() // length will be 5. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +length := slice.Length() +fmt.Println(length) // 5 ``` ### Make Empties the slice and sets it to a specified length. ```Go -s := &slice.Slice[int]{10, 20, 30} -s.Make(3) // s will be an empty Slice of length 3. +newSlice := (&slice.Slice[int]{}).Make(3) +fmt.Println(newSlice) // &[0, 0, 0] ``` ### MakeEach Empties the slice, sets it to a specified length, and populates it with provided values. ```Go -s := &slice.Slice[int]{} -s.MakeEach(10, 20, 30) // s will be a Slice containing {10, 20, 30}. +newSlice := (&slice.Slice[int]{}).MakeEach(1, 2, 3) +fmt.Println(newSlice) // &[1, 2, 3] ``` ### MakeEachReverse Empties the slice, sets it to a specified length, and populates it with provided values in reverse order. ```Go -s := &slice.Slice[int]{} -s.MakeEachReverse(10, 20, 30) // s will be a Slice containing {30, 20, 10}. +newSlice := (&slice.Slice[int]{}).MakeEachReverse(1, 2, 3) +fmt.Println(newSlice) // &[3, 2, 1] ``` ### Map Executes a provided function for each element and sets the returned value to a new slice at the current index. ```Go -s := &slice.Slice[int]{10, 20, 30} -s.Map(func(i int, value int) int { - return value * 2 -}) // s will be a Slice containing {20, 40, 60}. +newSlice := &slice.Slice[int]{1, 2, 3} +mappedSlice := slice.Map(func(i int, value int) int { + return value * 2 +}) +fmt.Println(mappedSlice) // &[2, 4, 6] ``` ### MapReverse Executes a provided function for each element in reverse order and sets the returned value to a new slice at the current index. ```Go -s := &slice.Slice[int]{10, 20, 30} -s.MapReverse(func(i int, value int) int { - return value * 2 -}) // s will be a Slice containing {60, 40, 20}. +newSlice := &slice.Slice[int]{1, 2, 3} +mappedSlice := slice.MapReverse(func(i int, value int) int { + return value * 2 +}) +fmt.Println(mappedSlice) // &[6, 4, 2] ``` ### Modify Modify applies the provided function to each element in the slice and modifies the elements in place. ```Go -s := slice.Slice[int]{1, 2, 3, 4, 5} -modifiedSlice := numbers.Modify(func(i int, value int) int { - return value * 2 +newSlice := &slice.Slice[int]{1, 2, 3} +newSlice.Modify(func(i int, value int) int { + return value + 10 }) -// modifiedSlice: [2, 4, 6, 8, 10]. +fmt.Println(slice) // &[11, 12, 13] ``` -###ModifyReverseModifyReverse +### ModifyReverseModifyReverse Modify applies the provided function to each element in the slice in reverse order and modifies the elements in place. ```Go -s := slice.Slice[int]{1, 2, 3, 4, 5} -modifiedSlice := numbers.Modify(func(i int, value int) int { - return value * 2 +newSlice := &slice.Slice[int]{1, 2, 3} +newSlice.ModifyReverse(func(i int, value int) int { + return value + 10 }) -// modifiedSlice: [2, 4, 6, 8, 10]. +fmt.Println(slice) // &[13, 12, 11] ``` ### Poll Removes and returns the first element from the slice. ```Go -s := &slice.Slice[int]{10, 20, 30} -value := s.Poll() // value will be 10, and s will be [20, 30]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +value := slice.Poll() +fmt.Println(value) // 1 ``` ### PollLength Removes the first element from the slice and returns the removed element and the length of the modified slice. ```Go -s := &slice.Slice[int]{10, 20, 30} -value, length := s.Poll() // value will be 10, length will be 2, and s will be [20, 30]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +value, length := slice.PollLength() +fmt.Println(value, length) // 1, 4 ``` ### PollOK Removes and returns the first element from the slice and returns a boolean indicating success. ```Go -s := slice.Slice[int]{1, 2, 3} -value, ok := s.PollOK() // 'value' will be 1, and 'ok' will be true as the slice is not empty. +newSlice := &slice.Slice[int]{1, 2, 3} +value, ok := slice.PollOK() +fmt.Println(value, ok) // 1, true ``` ### Pop Removes and returns the last element from the slice. ```Go -s := &slice.Slice[int]{1, 2, 3} -value := s.Pop() -// 'value' will be 3, and the slice will become [1, 2]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +value := slice.Pop() +fmt.Println(value) // 5 ``` ### PopLength Removes the last element from the slice and returns the removed element and the length of the modified slice. ```Go -s := &slice.Slice[int]{10, 20, 30} -value, length := s.PopLength() // value will be 30, length will be 2, and s will be [10, 20]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +value, length := slice.PopLength() +fmt.Println(value, length) // 5, 4 ``` ### PopOK Removes and returns the last element from the slice and returns a boolean indicating success. ```Go -s := &slice.Slice[int]{10, 20, 30} -value, ok := s.PopOK() // value will be 30, ok will be true, and s will be [10, 20]. +newSlice := &slice.Slice[int]{1, 2, 3} +value, ok := slice.PopOK() +fmt.Println(value, ok) // 3, true ``` ### Precatenate Merges elements from another slice to the head of the receiver slice. ```Go -s1 := &slice.Slice[int]{1, 2, 3} -s2 := &slice.Slice[int]{4, 5} -s1.Precatenate(s2) // s1 will be [4, 5, 1, 2, 3]. +slice1 := &slice.Slice[int]{1, 2} +slice2 := &slice.Slice[int]{3, 4} +slice1.Precatenate(slice2) +fmt.Println(slice1) // &[1, 2, 3, 4] ``` ### PrecatenateFunc Prepends elements from another slice based on a provided predicate function. ```Go -s1 := &slice.Slice[int]{1, 2, 3} -s2 := &slice.Slice[int]{4, 5, 6} -result := s1.PrecatenateFunc(s2, func(i int, value int) bool { - return value%2 == 0 -}) // s1 will be modified to [6, 4, 2, 1, 3], and 'result' will be a pointer to 's1'. +slice1 := &slice.Slice[int]{1, 2, 3} +slice2 := &slice.Slice[int]{3, 4, 5} +slice1.PrecatenateFunc(slice2, func(i int, value int) bool { + return value%2 == 0 +}) +fmt.Println(slice1) // &[2, 4] ``` ### PrecatenateLength Merges elements from another slice to the head of the receiver slice and returns the length of the modified slice. ```Go -s1 := &slice.Slice[int]{1, 2, 3} -s2 := &slice.Slice[int]{4, 5} -length := s1.PrecatenateLength(s2) // length will be 5, and s1 will be [4, 5, 1, 2, 3]. +slice1 := &slice.Slice[int]{1, 2} +slice2 := &slice.Slice[int]{3, 4} +length := slice1.PrecatenateLength(slice2) +fmt.Println(length) // 4 ``` ### Prepend Adds one element to the head of the slice. ```Go -s := &slice.Slice[int]{2, 3} -s.Prepend(1) // s will be [1, 2, 3]. +newSlice := &slice.Slice[int]{3, 4, 5} +newSlice.Prepend(1, 2) +fmt.Println(newSlice) // &[1, 2, 3, 4, 5] ``` ### PrependFunc Prepends elements to the head of the slice based on a provided predicate function. ```Go -s := &slice.Slice[int]{1, 2, 3} -result := s.PrependFunc([]int{4, 5, 6}, func(i int, value int) bool { - return value%2 == 0 -}) // 's' will be modified to [6, 4, 2, 1, 3], and 'result' will be a pointer to 's'. +newSlice := &slice.Slice[int]{3, 4, 5} +values := []int{1, 2} +slice.PrependFunc(values, func(i int, value int) bool { + return value%2 == 0 +}) +fmt.Println(newSlice) // &[2, 4, 3, 4, 5] ``` ### PrependLength Adds multiple elements to the head of the slice and returns the length of the modified slice. ```Go -s := &slice.Slice[int]{2, 3} -length := s.PrependLength(1, 0) // length will be 4, and s will be [1, 0, 2, 3]. +newSlice := &slice.Slice[int]{3, 4, 5} +length := newSlice.PrependLength(1, 2) +fmt.Println(length) // 5 ``` ### Reduce Reduce applies the provided function to each element in the slice and reduces the elements to a single value. ```Go -s := slice.Slice[int]({1, 2, 3, 4, 5}) -sum := numbers.Reduce(func(i int, currentValue int, resultValue int) int { +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +result := newSlice.Reduce(func(i int, currentValue int, resultValue int) int { return resultValue + currentValue }) -// sum: 15 (1 + 2 + 3 + 4 + 5). +fmt.Println(result) // 15 ``` ### ReduceReverse ReduceReverse iterates over the slice in reverse order and reduces the elements into a single value using the provided function. ```Go -s := slice.Slice[int]{1, 2, 3, 4, 5} -sum := numbers.ReduceReverse(func(i int, currentValue, resultValue int) int { - return currentValue + resultValue +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +result := newSlice.ReduceReverse(func(i int, currentValue int, resultValue int) int { + return resultValue + currentValue }) -// sum: 15 (sum of all elements in the slice). +fmt.Println(result) // 15 ``` ### Replace Replaces the element at the index with the provided value. ```Go -s := &slice.Slice[int]{1, 2, 3} -ok := s.Replace(1, 4) // ok will be true, and s will be [1, 4, 3]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +success := slice.Replace(2, 10) +fmt.Println(slice) // &[1, 2, 10, 4, 5] +fmt.Println(success) // true ``` ### Reverse Reverses the order of the slice. ```Go -s := &slice.Slice[int]{1, 2, 3} -s.Reverse() // s will be [3, 2, 1]. -``` - -### Set -Creates a new slice containing opnly unique values. -```Go -s := &slice.Slice[int]{1, 2, 2, 3, 3, 3} -s.Set() // s will be [1, 2, 3]. +newSlice := &slice.Slice[int]{1, 2, 3} +newSlice.Reverse() +fmt.Println(newSlice) // &[3, 2, 1] ``` ### Shuffle Randomly shuffles elements in the slice. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -s.Shuffle() // s will be a random permutation of [1, 2, 3, 4, 5]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +newSlice.Shuffle() +fmt.Println(newSlice) // Randomly shuffled slice ``` ### Slice Creates a subset of the values based on the beginning and end index. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -newSlice := s.Slice(1, 3) // newSlice will be [2, 3, 4]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +subSlice := newSlice.Slice(1, 4) +fmt.Println(subSlice) // &[2, 3, 4] ``` ### SortFunc Sorts elements in the slice that satisfy a provided predicate function. ```Go -s := &slice.Slice[int]{2, 1, 5, 3} -s.SortFunc(func(i int, j int, a int, b int) bool { - return a < b -}) // s will be [1, 2, 3, 5]. +newSlice := &slice.Slice[int]{5, 2, 1, 4, 3} +newSlice.SortFunc(func(i int, j int, a int, b int) bool { + return a < b +}) +fmt.Println(newSlice) // &[1, 2, 3, 4, 5] ``` ### Splice Modifies the slice to include only the values based on the beginning and end index. ```Go -s := &slice.Slice[int]{1, 2, 3, 4, 5} -slice.Split(1, 3) // s will be [2, 3, 4]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +splicedSlice := newSlice.Splice(1, 3) +fmt.Println(splicedSlice) // &[2, 3] ``` ### Split Divides the slice into two slices at the specified index and returns the two new slices. ```Go -s := &slice.Slice[int]{1, 2, 3, 4} -a, b := s.Split(2) // a will be [1, 2], be will be [3, 4]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +left, right := newSlice.Split(2) +fmt.Println(left, right) // &[1, 2], &[3, 4, 5] ``` ### SplitFunc Divides the slice into two slices based on the provided function and returns the two new slices. ```Go -s := &slice.Slice[int]{1, 2, 3, 4} -a, b := s.SplitFunc(func(i int, value int) bool { - return value%2 == 0 -}) // a will be [1, 3], b will be [2, 4]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +left, right := newSlice.SplitFunc(func(i int, value int) bool { + return value > 2 +}) +fmt.Println(left, right) // &[1, 2], &[3, 4, 5] ``` ### SplitOK Divides the slice into two slices at the specified index and returns the two new slices, or false if the index is invalid. ```Go -s := &slice.Slice[int]{1, 2, 3, 4} -a, b, ok := s.Split(2) // a will be [1, 2], be will be [3, 4], ok will be true. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +left, right, exists := newSlice.SplitOK(2) +fmt.Println(left, right, exists) // &[1, 2], &[3, 4, 5], true ``` ### Swap Swaps values at indexes i and j. ```Go -s := &slice.Slice[int]{1, 2, 3} -s.Swap(0, 2) // s will be [3, 2, 1]. +newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +newSlice.Swap(0, 4) +fmt.Println(newSlice) // &[5, 2, 3, 4, 1] ``` ## Examples diff --git a/slice.go b/slice.go index 38417f3..df2299a 100644 --- a/slice.go +++ b/slice.go @@ -11,12 +11,23 @@ import ( type Slice[T any] []T // Append appends the given values to the slice and returns the modified slice. +// +// newSlice := &slice.Slice[int]{} +// newSlice.Append(1, 2) +// fmt.Println(newSlice) // &[1, 2] func (slice *Slice[T]) Append(values ...T) *Slice[T] { *slice = append(*slice, values...) return slice } // AppendFunc appends values to the slice based on the provided function and returns the modified slice. +// +// newSlice := &slice.Slice[int]{} +// values := []int{1, 2, 3, 4, 5} +// newSlice.AppendFunc(values, func(i int, value int) bool { +// return value%2 == 0 +// }) +// fmt.Println(newSlice) // &[2, 4] func (slice *Slice[T]) AppendFunc(values []T, fn func(i int, value T) bool) *Slice[T] { for i, value := range values { if fn(i, value) { @@ -27,43 +38,76 @@ func (slice *Slice[T]) AppendFunc(values []T, fn func(i int, value T) bool) *Sli } // AppendLength appends values to the slice and returns the length of the modified slice. +// +// newSlice := &slice.Slice[int]{} +// length := newSlice.AppendLength(1, 2, 3) +// fmt.Println(length) // 3 func (slice *Slice[T]) AppendLength(values ...T) int { return slice.Append(values...).Length() } // Bounds checks if the given index is within the bounds of the slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// isWithinBounds := newSlice.Bounds(2) +// fmt.Println(isWithinBounds) // true func (slice *Slice[T]) Bounds(i int) bool { return i >= 0 && i < slice.Length() } // Clone creates a new slice that is a copy of the original slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// cloneSlice := newSlice.Clone() +// fmt.Println(cloneSlice) // &[1, 2, 3] func (slice *Slice[T]) Clone() *Slice[T] { - s := *slice - return &s + newSlice := *slice + return &newSlice } // Concatenate concatenates the given slice with the original slice and returns the modified slice. -func (slice *Slice[T]) Concatenate(s *Slice[T]) *Slice[T] { - if s != nil { - slice.Append((*s)...) +// +// slice1 := &slice.Slice[int]{1, 2} +// slice2 := &slice.Slice[int]{3, 4} +// slice1.Concatenate(slice2) +// fmt.Println(newSlice) // &[1, 2, 3, 4] +func (slice *Slice[T]) Concatenate(otherSlice *Slice[T]) *Slice[T] { + if otherSlice != nil { + slice.Append((*otherSlice)...) } return slice } // ConcatenateFunc concatenates values based on the provided function and returns the modified slice. -func (slice *Slice[T]) ConcatenateFunc(s *Slice[T], fn func(i int, value T) bool) *Slice[T] { - if s != nil { - slice.AppendFunc(*s, fn) +// +// slice1 := &slice.Slice[int]{1, 2, 3} +// slice2 := &slice.Slice[int]{4, 5, 6} +// slice1.ConcatenateFunc(slice2, func(i int, value int) bool { +// return value%2 == 0 +// }) +// fmt.Println(slice1) // &[2, 4, 6] +func (slice *Slice[T]) ConcatenateFunc(otherSlice *Slice[T], fn func(i int, value T) bool) *Slice[T] { + if otherSlice != nil { + slice.AppendFunc(*otherSlice, fn) } return slice } // ConcatenateLength concatenates the given slice with the original slice and returns the length of the modified slice. -func (slice *Slice[T]) ConcatenateLength(s *Slice[T]) int { - return slice.Concatenate(s).Length() +// +// slice1 := &slice.Slice[int]{1, 2} +// slice2 := &slice.Slice[int]{3, 4} +// length := slice1.ConcatenateLength(slice2) +// fmt.Println(length) // 4 +func (slice *Slice[T]) ConcatenateLength(otherSlice *Slice[T]) int { + return slice.Concatenate(otherSlice).Length() } // Contains checks if the slice contains the given value. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// contains := slice.Contains(2) +// fmt.Println(contains) // true func (slice *Slice[T]) Contains(value T) bool { var ok bool slice.EachBreak(func(i int, v T) bool { @@ -74,15 +118,23 @@ func (slice *Slice[T]) Contains(value T) bool { } // ContainsMany checks if the slice contains any of the given values and returns a boolean slice indicating the results. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// contains := slice.ContainsMany(2, 6) +// fmt.Println(contains) // &[true, false] func (slice *Slice[T]) ContainsMany(values ...T) *Slice[bool] { - s := &Slice[bool]{} + newSlice := &Slice[bool]{} for _, value := range values { - s.Append(slice.Contains(value)) + newSlice.Append(slice.Contains(value)) } - return s + return newSlice } // Deduplicate removes duplicate values from the slice and returns the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 2, 3, 4, 4, 5} +// newSlice.Deduplicate() +// fmt.Println(newSlice) // &[1, 2, 3, 4, 5] func (slice *Slice[T]) Deduplicate() *Slice[T] { uniqueValues := make(map[string]bool) var uniqueSlice Slice[T] @@ -98,6 +150,10 @@ func (slice *Slice[T]) Deduplicate() *Slice[T] { } // Delete removes the element at the specified index from the slice and returns the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// newSlice := slice.Delete(2) +// fmt.Println(newSlice) // &[1, 2, 4, 5] func (slice *Slice[T]) Delete(i int) *Slice[T] { if slice.Bounds(i) { slice.DeleteUnsafe(i) @@ -106,6 +162,12 @@ func (slice *Slice[T]) Delete(i int) *Slice[T] { } // DeleteFunc removes elements from the slice based on the provided function and returns the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// newSlice.DeleteFunc(func(i int, value int) bool { +// return value%2 == 0 +// }) +// fmt.Println(newSlice) // &[1, 3, 5] func (slice *Slice[T]) DeleteFunc(fn func(i int, value T) bool) *Slice[T] { length := slice.Length() for i := 0; i < length; i++ { @@ -119,11 +181,19 @@ func (slice *Slice[T]) DeleteFunc(fn func(i int, value T) bool) *Slice[T] { } // DeleteLength removes the element at the specified index from the slice and returns the length of the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// length := slice.DeleteLength(2) +// fmt.Println(length) // 4 func (slice *Slice[T]) DeleteLength(i int) int { return slice.Delete(i).Length() } // DeleteOK removes the element at the specified index from the slice if it exists and returns true, or false otherwise. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// success := slice.DeleteOK(2) +// fmt.Println(success) // true func (slice *Slice[T]) DeleteOK(i int) bool { if slice.Bounds(i) { slice.Delete(i) @@ -133,12 +203,25 @@ func (slice *Slice[T]) DeleteOK(i int) bool { } // DeleteUnsafe removes the element at the specified index from the slice without performing bounds checks and returns the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// newSlice.DeleteUnsafe(2) +// fmt.Println(newSlice) // &[1, 2, 4, 5] func (slice *Slice[T]) DeleteUnsafe(i int) *Slice[T] { *slice = append((*slice)[:i], (*slice)[i+1:]...) return slice } // Each applies the given function to each element of the slice and returns the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// newSlice.Each(func(i int, value int) { +// fmt.Println(value) +// }) +// // Output: +// // 1 +// // 2 +// // ... func (slice *Slice[T]) Each(fn func(i int, value T)) *Slice[T] { slice.EachBreak(func(i int, value T) bool { fn(i, value) @@ -148,6 +231,16 @@ func (slice *Slice[T]) Each(fn func(i int, value T)) *Slice[T] { } // EachBreak applies the given function to each element of the slice until the function returns false and returns the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// newSlice.EachBreak(func(i int, value int) bool { +// fmt.Println(value) +// return value == 3 +// }) +// // Output: +// // 1 +// // 2 +// // 3 func (slice *Slice[T]) EachBreak(fn func(i int, value T) bool) *Slice[T] { for i, v := range *slice { if !fn(i, v) { @@ -158,6 +251,12 @@ func (slice *Slice[T]) EachBreak(fn func(i int, value T) bool) *Slice[T] { } // EachOK applies the given function to each element of the slice and returns true if the function returned true for all elements, or false otherwise. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// allPositive := slice.EachOK(func(i int, value int) bool { +// return value > 0 +// }) +// fmt.Println(allPositive) // true func (slice *Slice[T]) EachOK(fn func(i int, value T) bool) bool { var ok bool slice.EachBreak(func(i int, value T) bool { @@ -168,6 +267,15 @@ func (slice *Slice[T]) EachOK(fn func(i int, value T) bool) bool { } // EachReverse applies the given function to each element of the slice in reverse order and returns the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// newSlice.EachReverse(func(i int, value int) { +// fmt.Println(value) +// }) +// // Output: +// // 5 +// // 4 +// // ... func (slice *Slice[T]) EachReverse(fn func(i int, value T)) *Slice[T] { slice.EachReverseBreak(func(i int, value T) bool { fn(i, value) @@ -177,6 +285,16 @@ func (slice *Slice[T]) EachReverse(fn func(i int, value T)) *Slice[T] { } // EachReverseBreak applies the given function to each element of the slice in reverse order until the function returns false and returns the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// newSlice.EachReverseBreak(func(i int, value int) bool { +// fmt.Println(value) +// return value == 3 +// }) +// // Output: +// // 5 +// // 4 +// // 3 func (slice *Slice[T]) EachReverseBreak(fn func(i int, value T) bool) *Slice[T] { for i := slice.Length() - 1; i >= 0; i-- { if !fn(i, (*slice)[i]) { @@ -187,6 +305,12 @@ func (slice *Slice[T]) EachReverseBreak(fn func(i int, value T) bool) *Slice[T] } // EachReverseOK applies the given function to each element of the slice in reverse order and returns true if the function returned true for all elements, or false otherwise. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// allPositive := slice.EachReverseOK(func(i int, value int) bool { +// return value > 0 +// }) +// fmt.Println(allPositive) // true func (slice *Slice[T]) EachReverseOK(fn func(i int, value T) bool) bool { var ok bool slice.EachReverseBreak(func(i int, value T) bool { @@ -197,54 +321,91 @@ func (slice *Slice[T]) EachReverseOK(fn func(i int, value T) bool) bool { } // Equal checks if the slice is equal to another slice based on the element values. -func (slice *Slice[T]) Equal(s *Slice[T]) bool { - return slice.EqualFunc(s, func(i int, value1, value2 T) bool { +// +// slice1 := &slice.Slice[int]{1, 2, 3} +// slice2 := &slice.Slice[int]{1, 2, 3} +// isEqual := slice1.Equal(slice2) +// fmt.Println(isEqual) // true +func (slice *Slice[T]) Equal(otherSlice *Slice[T]) bool { + return slice.EqualFunc(otherSlice, func(i int, value1, value2 T) bool { return reflect.DeepEqual(value1, value2) }) } // EqualFunc checks if the slice is equal to another slice based on the element values and a provided comparison function. -func (slice *Slice[T]) EqualFunc(s *Slice[T], fn func(i int, a T, b T) bool) bool { - if !slice.EqualLength(s) { +// +// slice1 := &slice.Slice[int]{1, 2, 3} +// slice2 := &slice.Slice[int]{2, 3, 4} +// isEqual := slice1.EqualFunc(slice2, func(i int, a int, b int) bool { +// return a == b-1 +// }) +// fmt.Println(isEqual) // true +func (slice *Slice[T]) EqualFunc(otherSlice *Slice[T], fn func(i int, a T, b T) bool) bool { + if !slice.EqualLength(otherSlice) { return false } var ok bool slice.EachBreak(func(i int, value T) bool { - ok = fn(i, slice.Fetch(i), s.Fetch(i)) + ok = fn(i, slice.Fetch(i), otherSlice.Fetch(i)) return ok }) return ok } // EqualLength checks if the length of the slice is equal to the length of another slice. -func (slice *Slice[T]) EqualLength(s *Slice[T]) bool { - return slice.Length() == s.Length() +// +// slice1 := &slice.Slice[int]{1, 2, 3} +// slice2 := &slice.Slice[int]{4, 5, 6} +// isEqualLength := slice1.EqualLength(slice2) +// fmt.Println(isEqualLength) // true +func (slice *Slice[T]) EqualLength(otherSlice *Slice[T]) bool { + return slice.Length() == otherSlice.Length() } // Fetch returns the element at the specified index and a boolean indicating whether the index is valid. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// value := slice.Fetch(1) +// fmt.Println(value) // 2 func (slice *Slice[T]) Fetch(i int) T { value, _ := slice.Get(i) return value } // FetchLength returns the element at the specified index, a boolean indicating whether the index is valid, and the length of the slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// value, length := slice.FetchLength(2) +// fmt.Println(value, length) // 3, 5 func (slice *Slice[T]) FetchLength(i int) (T, int) { return slice.Fetch(i), slice.Length() } // Filter returns a new slice containing elements that satisfy the provided function. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// filteredSlice := slice.Filter(func(i int, value int) bool { +// return value%2 == 0 +// }) +// fmt.Println(filteredSlice) // &[2, 4] func (slice *Slice[T]) Filter(fn func(i int, value T) bool) *Slice[T] { - s := &Slice[T]{} + newSlice := &Slice[T]{} slice.Each(func(i int, value T) { if fn(i, value) { - s.Append(value) + newSlice.Append(value) } }) - return s + return newSlice } // FindIndex finds the index of the first element that satisfies the provided function and returns the index and true, // or -1 and false if no such element is found. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// index, found := slice.FindIndex(func(value int) bool { +// return value == 3 +// }) +// fmt.Println(index, found) // 2, true func (slice *Slice[T]) FindIndex(fn func(value T) bool) (int, bool) { for i, value := range *slice { if fn(value) { @@ -255,6 +416,10 @@ func (slice *Slice[T]) FindIndex(fn func(value T) bool) (int, bool) { } // Get returns the element at the specified index and a boolean indicating whether the index is valid. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// value, found := slice.Get(1) +// fmt.Println(value, found) // 2, true func (slice *Slice[T]) Get(i int) (T, bool) { var value T if !slice.Bounds(i) { @@ -264,33 +429,55 @@ func (slice *Slice[T]) Get(i int) (T, bool) { } // GetLength returns the element at the specified index, a boolean indicating whether the index is valid, and the length of the slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// value, found, length := slice.GetLength(2) +// fmt.Println(value, found, length) // 3, true, 5 func (slice *Slice[T]) GetLength(i int) (T, bool, int) { value, ok := slice.Get(i) return value, ok, slice.Length() } // IsEmpty returns true if the slice is empty, or false otherwise. +// +// newSlice := &slice.Slice[int]{} +// isEmpty := newSlice.IsEmpty() +// fmt.Println(isEmpty) // true func (slice *Slice[T]) IsEmpty() bool { return slice.Length() == 0 } // IsPopulated returns true if the slice is not empty, or false otherwise. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// isPopulated := newSlice.IsPopulated() +// fmt.Println(isPopulated) // true func (slice *Slice[T]) IsPopulated() bool { return !slice.IsEmpty() } // Length returns the length of the slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// length := slice.Length() +// fmt.Println(length) // 5 func (slice *Slice[T]) Length() int { return len(*slice) } // Make creates a new slice with the specified length and capacity and returns the modified slice. +// +// newSlice := (&slice.Slice[int]{}).Make(3) +// fmt.Println(newSlice) // &[0, 0, 0] func (slice *Slice[T]) Make(i int) *Slice[T] { *slice = make(Slice[T], i) return slice } // MakeEach creates a new slice with the specified elements and returns the modified slice. +// +// newSlice := (&slice.Slice[int]{}).MakeEach(1, 2, 3) +// fmt.Println(newSlice) // &[1, 2, 3] func (slice *Slice[T]) MakeEach(v ...T) *Slice[T] { return slice.Make(len(v)).Each(func(i int, _ T) { slice.Replace(i, v[i]) @@ -298,6 +485,9 @@ func (slice *Slice[T]) MakeEach(v ...T) *Slice[T] { } // MakeEachReverse creates a new slice with the specified elements in reverse order and returns the modified slice. +// +// newSlice := (&slice.Slice[int]{}).MakeEachReverse(1, 2, 3) +// fmt.Println(newSlice) // &[3, 2, 1] func (slice *Slice[T]) MakeEachReverse(values ...T) *Slice[T] { currentOffset := 0 return slice.Make(len(values)).EachReverse(func(i int, _ T) { @@ -307,24 +497,42 @@ func (slice *Slice[T]) MakeEachReverse(values ...T) *Slice[T] { } // Map applies the given function to each element of the slice and returns a new slice with the modified elements. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// mappedSlice := slice.Map(func(i int, value int) int { +// return value * 2 +// }) +// fmt.Println(mappedSlice) // &[2, 4, 6] func (slice *Slice[T]) Map(fn func(i int, value T) T) *Slice[T] { - s := make(Slice[T], slice.Length()) + newSlice := make(Slice[T], slice.Length()) slice.Each(func(i int, value T) { - s.Replace(i, fn(i, value)) + newSlice.Replace(i, fn(i, value)) }) - return &s + return &newSlice } // MapReverse applies the given function to each element of the slice in reverse order and returns a new slice with the modified elements. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// mappedSlice := slice.MapReverse(func(i int, value int) int { +// return value * 2 +// }) +// fmt.Println(mappedSlice) // &[6, 4, 2] func (slice *Slice[T]) MapReverse(fn func(i int, value T) T) *Slice[T] { - s := make(Slice[T], slice.Length()) + newSlice := make(Slice[T], slice.Length()) slice.EachReverse(func(i int, value T) { - s.Replace(i, fn(i, value)) + newSlice.Replace(i, fn(i, value)) }) - return &s + return &newSlice } // Modify applies the given function to each element of the slice and modifies the original slice with the modified elements. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// newSlice.Modify(func(i int, value int) int { +// return value + 10 +// }) +// fmt.Println(slice) // &[11, 12, 13] func (slice *Slice[T]) Modify(fn func(i int, value T) T) *Slice[T] { slice.Each(func(i int, value T) { slice.Replace(i, fn(i, value)) @@ -333,6 +541,12 @@ func (slice *Slice[T]) Modify(fn func(i int, value T) T) *Slice[T] { } // ModifyReverse applies the given function to each element of the slice in reverse order and modifies the original slice with the modified elements. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// newSlice.ModifyReverse(func(i int, value int) int { +// return value + 10 +// }) +// fmt.Println(slice) // &[13, 12, 11] func (slice *Slice[T]) ModifyReverse(fn func(i int, value T) T) *Slice[T] { slice.EachReverse(func(i int, value T) { slice.Replace(i, fn(i, value)) @@ -341,6 +555,10 @@ func (slice *Slice[T]) ModifyReverse(fn func(i int, value T) T) *Slice[T] { } // Poll removes and returns the first element of the slice, or a zero value if the slice is empty. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// value := slice.Poll() +// fmt.Println(value) // 1 func (slice *Slice[T]) Poll() T { var value T if !slice.IsEmpty() { @@ -351,11 +569,19 @@ func (slice *Slice[T]) Poll() T { } // PollLength removes and returns the first element of the slice and the length of the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// value, length := slice.PollLength() +// fmt.Println(value, length) // 1, 4 func (slice *Slice[T]) PollLength() (T, int) { return slice.Poll(), slice.Length() } // PollOK removes and returns the first element of the slice and true if the slice is not empty, or a zero value and false otherwise. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// value, ok := slice.PollOK() +// fmt.Println(value, ok) // 1, true func (slice *Slice[T]) PollOK() (T, bool) { if slice.IsEmpty() { var value T @@ -365,6 +591,10 @@ func (slice *Slice[T]) PollOK() (T, bool) { } // Pop removes and returns the last element of the slice, or a zero value if the slice is empty. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// value := slice.Pop() +// fmt.Println(value) // 5 func (slice *Slice[T]) Pop() T { var value T if slice.IsPopulated() { @@ -376,11 +606,19 @@ func (slice *Slice[T]) Pop() T { } // PopLength removes and returns the last element of the slice and the length of the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// value, length := slice.PopLength() +// fmt.Println(value, length) // 5, 4 func (slice *Slice[T]) PopLength() (T, int) { return slice.Pop(), slice.Length() } // PopOK removes and returns the last element of the slice and true if the slice is not empty, or a zero value and false otherwise. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// value, ok := slice.PopOK() +// fmt.Println(value, ok) // 3, true func (slice *Slice[T]) PopOK() (T, bool) { if slice.IsEmpty() { var value T @@ -390,47 +628,85 @@ func (slice *Slice[T]) PopOK() (T, bool) { } // Precatenate concatenates the given slice with the original slice and returns the modified slice. -func (slice *Slice[T]) Precatenate(s *Slice[T]) *Slice[T] { - if s != nil { - slice.Prepend((*s)...) +// +// slice1 := &slice.Slice[int]{1, 2} +// slice2 := &slice.Slice[int]{3, 4} +// slice1.Precatenate(slice2) +// fmt.Println(slice1) // &[1, 2, 3, 4] +func (slice *Slice[T]) Precatenate(otherSlice *Slice[T]) *Slice[T] { + if otherSlice != nil { + slice.Prepend((*otherSlice)...) } return slice } // PrecatenateFunc concatenates values based on the provided function and returns the modified slice. -func (slice *Slice[T]) PrecatenateFunc(s *Slice[T], fn func(i int, value T) bool) *Slice[T] { - return slice.PrependFunc(*s, fn) +// +// slice1 := &slice.Slice[int]{1, 2, 3} +// slice2 := &slice.Slice[int]{3, 4, 5} +// slice1.PrecatenateFunc(slice2, func(i int, value int) bool { +// return value%2 == 0 +// }) +// fmt.Println(slice1) // &[2, 4] +func (slice *Slice[T]) PrecatenateFunc(otherSlice *Slice[T], fn func(i int, value T) bool) *Slice[T] { + return slice.PrependFunc(*otherSlice, fn) } // PrecatenateLength concatenates the given slice with the original slice and returns the length of the modified slice. -func (slice *Slice[T]) PrecatenateLength(s *Slice[T]) int { - return slice.Precatenate(s).Length() +// +// slice1 := &slice.Slice[int]{1, 2} +// slice2 := &slice.Slice[int]{3, 4} +// length := slice1.PrecatenateLength(slice2) +// fmt.Println(length) // 4 +func (slice *Slice[T]) PrecatenateLength(otherSlice *Slice[T]) int { + return slice.Precatenate(otherSlice).Length() } // Prepend adds the given values to the beginning of the slice and returns the modified slice. +// +// newSlice := &slice.Slice[int]{3, 4, 5} +// newSlice.Prepend(1, 2) +// fmt.Println(newSlice) // &[1, 2, 3, 4, 5] func (slice *Slice[T]) Prepend(values ...T) *Slice[T] { *slice = append(values, *slice...) return slice } // PrependFunc adds values to the beginning of the slice based on the provided function and returns the modified slice. +// +// newSlice := &slice.Slice[int]{3, 4, 5} +// values := []int{1, 2} +// newSlice.PrependFunc(values, func(i int, value int) bool { +// return value%2 == 0 +// }) +// fmt.Println(newSlice) // &[2, 4, 3, 4, 5] func (slice *Slice[T]) PrependFunc(values []T, fn func(i int, value T) bool) *Slice[T] { - s := &Slice[T]{} + newSlice := &Slice[T]{} for i, value := range values { if fn(i, value) { - s.Append(value) + newSlice.Append(value) } } - *slice = *s.Concatenate(slice) + *slice = *newSlice.Concatenate(slice) return slice } // PrependLength adds values to the beginning of the slice and returns the length of the modified slice. +// +// newSlice := &slice.Slice[int]{3, 4, 5} +// length := newSlice.PrependLength(1, 2) +// fmt.Println(length) // 5 func (slice *Slice[T]) PrependLength(values ...T) int { return slice.Prepend(values...).Length() } // Reduce applies the given function to each element of the slice and returns the reduced result value. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// result := newSlice.Reduce(func(i int, currentValue int, resultValue int) int { +// return resultValue + currentValue +// }) +// fmt.Println(result) // 15 func (slice *Slice[T]) Reduce(fn func(i int, currentValue T, resultValue T) T) T { var resultValue T slice.Each(func(i int, currentValue T) { @@ -440,6 +716,12 @@ func (slice *Slice[T]) Reduce(fn func(i int, currentValue T, resultValue T) T) T } // ReduceReverse applies the given function to each element of the slice in reverse order and returns the reduced result value. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// result := newSlice.ReduceReverse(func(i int, currentValue int, resultValue int) int { +// return resultValue + currentValue +// }) +// fmt.Println(result) // 15 func (slice *Slice[T]) ReduceReverse(fn func(i int, currentValue T, resultValue T) T) T { var resultValue T slice.EachReverse(func(i int, currentValue T) { @@ -449,6 +731,11 @@ func (slice *Slice[T]) ReduceReverse(fn func(i int, currentValue T, resultValue } // Replace replaces the element at the specified index with the given value and returns true if the index is valid, or false otherwise. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// success := slice.Replace(2, 10) +// fmt.Println(slice) // &[1, 2, 10, 4, 5] +// fmt.Println(success) // true func (slice *Slice[T]) Replace(i int, value T) bool { if slice.Bounds(i) { (*slice)[i] = value @@ -458,6 +745,10 @@ func (slice *Slice[T]) Replace(i int, value T) bool { } // Reverse reverses the elements of the slice and returns the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3} +// newSlice.Reverse() +// fmt.Println(newSlice) // &[3, 2, 1] func (slice *Slice[T]) Reverse() *Slice[T] { for i, j := 0, slice.Length()-1; i < j; i, j = i+1, j-1 { slice.Swap(i, j) @@ -466,6 +757,10 @@ func (slice *Slice[T]) Reverse() *Slice[T] { } // Shuffle shuffles the elements of the slice and returns the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// newSlice.Shuffle() +// fmt.Println(newSlice) // Randomly shuffled slice func (slice *Slice[T]) Shuffle() *Slice[T] { rand.Shuffle(slice.Length(), func(i, j int) { slice.Swap(i, j) @@ -474,25 +769,39 @@ func (slice *Slice[T]) Shuffle() *Slice[T] { } // Slice returns a new slice containing the elements from index i to j (inclusive) of the original slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// subSlice := newSlice.Slice(1, 4) +// fmt.Println(subSlice) // &[2, 3, 4] func (slice *Slice[T]) Slice(i int, j int) *Slice[T] { if j < i { i, j = j, i } - s := (*slice)[i : j+1] - return &s + newSlice := (*slice)[i : j+1] + return &newSlice } // SortFunc sorts the elements of the slice based on the provided comparison function and returns the modified slice. +// +// newSlice := &slice.Slice[int]{5, 2, 1, 4, 3} +// newSlice.SortFunc(func(i int, j int, a int, b int) bool { +// return a < b +// }) +// fmt.Println(newSlice) // &[1, 2, 3, 4, 5] func (slice *Slice[T]) SortFunc(fn func(i int, j int, a T, b T) bool) *Slice[T] { - s := *slice // Copy the slice to a new variable. - sort.Slice(s, func(i int, j int) bool { - return fn(i, j, s[i], s[j]) // Use the copied slice (v) instead of slice. + newSlice := *slice // Copy the slice to a new variable. + sort.Slice(newSlice, func(i int, j int) bool { + return fn(i, j, newSlice[i], newSlice[j]) // Use the copied slice (v) instead of slice. }) - *slice = s // Update the original slice with the sorted copy. + *slice = newSlice // Update the original slice with the sorted copy. return slice } // Splice removes elements from the slice starting from index i to j (inclusive) and returns the modified slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// splicedSlice := newSlice.Splice(1, 3) +// fmt.Println(splicedSlice) // &[2, 3] func (slice *Slice[T]) Splice(i int, j int) *Slice[T] { if j < i { i, j = j, i @@ -504,6 +813,10 @@ func (slice *Slice[T]) Splice(i int, j int) *Slice[T] { } // Split divides the slice into two slices at the specified index and returns the two new slices. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// left, right := newSlice.Split(2) +// fmt.Println(left, right) // &[1, 2], &[3, 4, 5] func (slice *Slice[T]) Split(i int) (*Slice[T], *Slice[T]) { if !slice.Bounds(i) { return nil, nil @@ -513,6 +826,12 @@ func (slice *Slice[T]) Split(i int) (*Slice[T], *Slice[T]) { } // SplitFunc divides the slice into two slices based on the provided function and returns the two new slices. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// left, right := newSlice.SplitFunc(func(i int, value int) bool { +// return value > 2 +// }) +// fmt.Println(left, right) // &[1, 2], &[3, 4, 5] func (slice *Slice[T]) SplitFunc(fn func(i int, value T) bool) (*Slice[T], *Slice[T]) { firstSlice, secondSlice := &Slice[T]{}, &Slice[T]{} slice.Each(func(i int, value T) { @@ -526,6 +845,10 @@ func (slice *Slice[T]) SplitFunc(fn func(i int, value T) bool) (*Slice[T], *Slic } // SplitOK divides the slice into two slices at the specified index and returns the two new slices, or false if the index is invalid. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// left, right, exists := newSlice.SplitOK(2) +// fmt.Println(left, right, exists) // &[1, 2], &[3, 4, 5], true func (slice *Slice[T]) SplitOK(i int) (*Slice[T], *Slice[T], bool) { if !slice.Bounds(i) { return nil, nil, false @@ -535,6 +858,10 @@ func (slice *Slice[T]) SplitOK(i int) (*Slice[T], *Slice[T], bool) { } // Swap swaps the elements at the specified indices in the slice. +// +// newSlice := &slice.Slice[int]{1, 2, 3, 4, 5} +// newSlice.Swap(0, 4) +// fmt.Println(newSlice) // &[5, 2, 3, 4, 1] func (slice *Slice[T]) Swap(i int, j int) { if slice.Bounds(i) && slice.Bounds(j) { (*slice)[i], (*slice)[j] = (*slice)[j], (*slice)[i]