mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-12 08:42:29 +08:00
feat: A more reasonable IndexOf function (#66)
This commit is contained in:
@@ -14,6 +14,13 @@ import (
|
|||||||
"github.com/duke-git/lancet/v2/lancetconstraints"
|
"github.com/duke-git/lancet/v2/lancetconstraints"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Create a static variable to store the hash table.
|
||||||
|
// This variable has the same lifetime as the entire program and can be shared by functions that are called more than once.
|
||||||
|
var (
|
||||||
|
memoryHashMap = make(map[string]map[any]int)
|
||||||
|
memoryHashCounter = make(map[string]int)
|
||||||
|
)
|
||||||
|
|
||||||
// Contain check if the target value is in the slice or not
|
// Contain check if the target value is in the slice or not
|
||||||
func Contain[T comparable](slice []T, target T) bool {
|
func Contain[T comparable](slice []T, target T) bool {
|
||||||
for _, item := range slice {
|
for _, item := range slice {
|
||||||
@@ -832,14 +839,44 @@ func Without[T comparable](slice []T, items ...T) []T {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexOf returns the index at which the first occurrence of a item is found in a slice or return -1 if the item cannot be found.
|
// IndexOf returns the index at which the first occurrence of an item is found in a slice or return -1 if the item cannot be found.
|
||||||
func IndexOf[T comparable](slice []T, item T) int {
|
func IndexOf[T comparable](arr []T, val T) int {
|
||||||
for i, v := range slice {
|
limit := 10
|
||||||
if v == item {
|
// gets the hash value of the array as the key of the hash table.
|
||||||
return i
|
key := fmt.Sprintf("%p", arr)
|
||||||
|
// determines whether the hash table is empty. If so, the hash table is created.
|
||||||
|
if memoryHashMap[key] == nil {
|
||||||
|
memoryHashMap[key] = make(map[any]int)
|
||||||
|
// iterate through the array, adding the value and index of each element to the hash table.
|
||||||
|
for i := len(arr) - 1; i >= 0; i-- {
|
||||||
|
memoryHashMap[key][arr[i]] = i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// update the hash table counter.
|
||||||
|
memoryHashCounter[key]++
|
||||||
|
|
||||||
|
// use the hash table to find the specified value. If found, the index is returned.
|
||||||
|
if index, ok := memoryHashMap[key][val]; ok {
|
||||||
|
// calculate the memory usage of the hash table.
|
||||||
|
size := len(memoryHashMap)
|
||||||
|
// If the memory usage of the hash table exceeds the memory limit, the hash table with the lowest counter is cleared.
|
||||||
|
if size > limit {
|
||||||
|
var minKey string
|
||||||
|
var minVal int
|
||||||
|
for k, v := range memoryHashCounter {
|
||||||
|
if k == key {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if minVal == 0 || v < minVal {
|
||||||
|
minKey = k
|
||||||
|
minVal = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete(memoryHashMap, minKey)
|
||||||
|
delete(memoryHashCounter, minKey)
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package slice
|
package slice
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -669,8 +670,39 @@ func TestIndexOf(t *testing.T) {
|
|||||||
assert := internal.NewAssert(t, "TestIndexOf")
|
assert := internal.NewAssert(t, "TestIndexOf")
|
||||||
|
|
||||||
arr := []string{"a", "a", "b", "c"}
|
arr := []string{"a", "a", "b", "c"}
|
||||||
|
key := fmt.Sprintf("%p", arr)
|
||||||
assert.Equal(0, IndexOf(arr, "a"))
|
assert.Equal(0, IndexOf(arr, "a"))
|
||||||
assert.Equal(-1, IndexOf(arr, "d"))
|
assert.Equal(-1, IndexOf(arr, "d"))
|
||||||
|
assert.Equal(2, memoryHashCounter[key])
|
||||||
|
|
||||||
|
arr1 := []int{1, 2, 3, 4, 5}
|
||||||
|
key1 := fmt.Sprintf("%p", arr1)
|
||||||
|
assert.Equal(3, IndexOf(arr1, 4))
|
||||||
|
assert.Equal(-1, IndexOf(arr1, 6))
|
||||||
|
assert.Equal(2, memoryHashCounter[key1])
|
||||||
|
|
||||||
|
arr2 := []float64{1.1, 2.2, 3.3, 4.4, 5.5}
|
||||||
|
key2 := fmt.Sprintf("%p", arr2)
|
||||||
|
assert.Equal(2, IndexOf(arr2, 3.3))
|
||||||
|
assert.Equal(3, IndexOf(arr2, 4.4))
|
||||||
|
assert.Equal(-1, IndexOf(arr2, 6.6))
|
||||||
|
assert.Equal(3, memoryHashCounter[key2])
|
||||||
|
|
||||||
|
for i := 0; i < 6; i++ {
|
||||||
|
a := []string{"a", "b", "c"}
|
||||||
|
IndexOf(a, "a")
|
||||||
|
IndexOf(a, "b")
|
||||||
|
}
|
||||||
|
minArr := []string{"c", "b", "a"}
|
||||||
|
minKey := fmt.Sprintf("%p", minArr)
|
||||||
|
assert.Equal(0, IndexOf(minArr, "c"))
|
||||||
|
|
||||||
|
arr3 := []string{"q", "w", "e"}
|
||||||
|
key3 := fmt.Sprintf("%p", arr3)
|
||||||
|
assert.Equal(1, IndexOf(arr3, "w"))
|
||||||
|
assert.Equal(-1, IndexOf(arr3, "r"))
|
||||||
|
assert.Equal(2, memoryHashCounter[key3])
|
||||||
|
assert.Equal(0, memoryHashCounter[minKey])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLastIndexOf(t *testing.T) {
|
func TestLastIndexOf(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user