mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
garray updates
This commit is contained in:
@ -8,7 +8,8 @@ package garray
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/gogf/gf/g/internal/rwmutex"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/g/internal/rwmutex"
|
||||
"github.com/gogf/gf/g/util/gconv"
|
||||
"github.com/gogf/gf/g/util/grand"
|
||||
"math"
|
||||
@ -16,24 +17,20 @@ import (
|
||||
)
|
||||
|
||||
type IntArray struct {
|
||||
mu *rwmutex.RWMutex // 互斥锁
|
||||
array []int // 底层数组
|
||||
mu *rwmutex.RWMutex
|
||||
array []int
|
||||
}
|
||||
|
||||
// Create an empty array.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 创建一个空的数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// NewIntArray creates and returns an empty array.
|
||||
// The param <unsafe> used to specify whether using array in un-concurrent-safety,
|
||||
// which is false in default.
|
||||
func NewIntArray(unsafe...bool) *IntArray {
|
||||
return NewIntArraySize(0, 0, unsafe...)
|
||||
}
|
||||
|
||||
// Create an array with given size and cap.
|
||||
// NewIntArraySize create and returns an array with given size and cap.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 创建一个指定大小的数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewIntArraySize(size int, cap int, unsafe...bool) *IntArray {
|
||||
return &IntArray{
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -41,11 +38,9 @@ func NewIntArraySize(size int, cap int, unsafe...bool) *IntArray {
|
||||
}
|
||||
}
|
||||
|
||||
// Create an array with given slice <array>.
|
||||
// NewIntArrayFrom creates and returns an array with given slice <array>.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 通过给定的slice变量创建数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewIntArrayFrom(array []int, unsafe...bool) *IntArray {
|
||||
return &IntArray{
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -53,11 +48,9 @@ func NewIntArrayFrom(array []int, unsafe...bool) *IntArray {
|
||||
}
|
||||
}
|
||||
|
||||
// Create an array from a copy of given slice <array>.
|
||||
// NewIntArrayFromCopy creates and returns an array from a copy of given slice <array>.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 通过给定的slice拷贝创建数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewIntArrayFromCopy(array []int, unsafe...bool) *IntArray {
|
||||
newArray := make([]int, len(array))
|
||||
copy(newArray, array)
|
||||
@ -67,9 +60,8 @@ func NewIntArrayFromCopy(array []int, unsafe...bool) *IntArray {
|
||||
}
|
||||
}
|
||||
|
||||
// Get value by index.
|
||||
//
|
||||
// 获取指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Get returns the value of the specified index,
|
||||
// the caller should notice the boundary of the array.
|
||||
func (a *IntArray) Get(index int) int {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -77,9 +69,7 @@ func (a *IntArray) Get(index int) int {
|
||||
return value
|
||||
}
|
||||
|
||||
// Set value by index.
|
||||
//
|
||||
// 设置指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Set sets value to specified index.
|
||||
func (a *IntArray) Set(index int, value int) *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -87,9 +77,7 @@ func (a *IntArray) Set(index int, value int) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Set the underlying slice array with the given <array> param.
|
||||
//
|
||||
// 设置底层数组变量.
|
||||
// SetArray sets the underlying slice array with the given <array>.
|
||||
func (a *IntArray) SetArray(array []int) *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -97,9 +85,7 @@ func (a *IntArray) SetArray(array []int) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Replace the array items by given <array> from the beginning of array.
|
||||
//
|
||||
// 使用指定数组替换到对应的索引元素值.
|
||||
// Replace replaces the array items by given <array> from the beginning of array.
|
||||
func (a *IntArray) Replace(array []int) *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -113,9 +99,7 @@ func (a *IntArray) Replace(array []int) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Calculate the sum of values in an array.
|
||||
//
|
||||
// 对数组中的元素项求和。
|
||||
// Sum returns the sum of values in an array.
|
||||
func (a *IntArray) Sum() (sum int) {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -125,11 +109,9 @@ func (a *IntArray) Sum() (sum int) {
|
||||
return
|
||||
}
|
||||
|
||||
// Sort the array in increasing order.
|
||||
// Sort sorts the array in increasing order.
|
||||
// The param <reverse> controls whether sort
|
||||
// in increasing order(default) or decreasing order
|
||||
//
|
||||
// 将数组排序(默认从低到高).
|
||||
func (a *IntArray) Sort(reverse...bool) *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -146,9 +128,7 @@ func (a *IntArray) Sort(reverse...bool) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Sort the array by custom function <less>.
|
||||
//
|
||||
// 使用自定义的排序函数将数组重新排序.
|
||||
// SortFunc sorts the array by custom function <less>.
|
||||
func (a *IntArray) SortFunc(less func(v1, v2 int) bool) *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -158,9 +138,7 @@ func (a *IntArray) SortFunc(less func(v1, v2 int) bool) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Insert the <value> to the front of <index>.
|
||||
//
|
||||
// 在当前索引位置前插入一个数据项, 调用方注意判断数组边界。
|
||||
// InsertBefore inserts the <value> to the front of <index>.
|
||||
func (a *IntArray) InsertBefore(index int, value int) *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -170,9 +148,7 @@ func (a *IntArray) InsertBefore(index int, value int) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Insert the <value> to the back of <index>.
|
||||
//
|
||||
// 在当前索引位置前插入一个数据项, 调用方注意判断数组边界。
|
||||
// InsertAfter inserts the <value> to the back of <index>.
|
||||
func (a *IntArray) InsertAfter(index int, value int) *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -182,13 +158,11 @@ func (a *IntArray) InsertAfter(index int, value int) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Remove an item by index.
|
||||
//
|
||||
// 删除指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Remove removes an item by index.
|
||||
func (a *IntArray) Remove(index int) int {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
// 边界删除判断,以提高删除效率
|
||||
// Determine array boundaries when deleting to improve deletion efficiency.
|
||||
if index == 0 {
|
||||
value := a.array[0]
|
||||
a.array = a.array[1 : ]
|
||||
@ -198,15 +172,15 @@ func (a *IntArray) Remove(index int) int {
|
||||
a.array = a.array[: index]
|
||||
return value
|
||||
}
|
||||
// 如果非边界删除,会涉及到数组创建,那么删除的效率差一些
|
||||
// If it is a non-boundary delete,
|
||||
// it will involve the creation of an array,
|
||||
// then the deletion is less efficient.
|
||||
value := a.array[index]
|
||||
a.array = append(a.array[ : index], a.array[index + 1 : ]...)
|
||||
return value
|
||||
}
|
||||
|
||||
// Push new items to the beginning of array.
|
||||
//
|
||||
// 将数据项添加到数组的最左端(索引为0)。
|
||||
// PushLeft pushes one or multiple items to the beginning of array.
|
||||
func (a *IntArray) PushLeft(value...int) *IntArray {
|
||||
a.mu.Lock()
|
||||
a.array = append(value, a.array...)
|
||||
@ -214,9 +188,8 @@ func (a *IntArray) PushLeft(value...int) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Push new items to the end of array.
|
||||
//
|
||||
// 将数据项添加到数组的最右端(索引为length - 1), 等于: Append。
|
||||
// PushRight pushes one or multiple items to the end of array.
|
||||
// It equals to Append.
|
||||
func (a *IntArray) PushRight(value...int) *IntArray {
|
||||
a.mu.Lock()
|
||||
a.array = append(a.array, value...)
|
||||
@ -224,9 +197,7 @@ func (a *IntArray) PushRight(value...int) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Pop an item from the beginning of array.
|
||||
//
|
||||
// 将最左端(索引为0)的数据项移出数组,并返回该数据项。
|
||||
// PopLeft pops and returns an item from the beginning of array.
|
||||
func (a *IntArray) PopLeft() int {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -235,9 +206,7 @@ func (a *IntArray) PopLeft() int {
|
||||
return value
|
||||
}
|
||||
|
||||
// Pop an item from the end of array.
|
||||
//
|
||||
// 将最右端(索引为length - 1)的数据项移出数组,并返回该数据项。
|
||||
// PopRight pops and returns an item from the end of array.
|
||||
func (a *IntArray) PopRight() int {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -247,16 +216,12 @@ func (a *IntArray) PopRight() int {
|
||||
return value
|
||||
}
|
||||
|
||||
// PopRand picks an random item out of array.
|
||||
//
|
||||
// 随机将一个数据项移出数组,并返回该数据项。
|
||||
// PopRand randomly pops and return an item out of array.
|
||||
func (a *IntArray) PopRand() int {
|
||||
return a.Remove(grand.Intn(len(a.array)))
|
||||
}
|
||||
|
||||
// PopRands picks <size> items out of array.
|
||||
//
|
||||
// 随机将size个数据项移出数组,并返回该数据项。
|
||||
// PopRands randomly pops and returns <size> items out of array.
|
||||
func (a *IntArray) PopRands(size int) []int {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -272,9 +237,7 @@ func (a *IntArray) PopRands(size int) []int {
|
||||
return array
|
||||
}
|
||||
|
||||
// Pop <size> items from the beginning of array.
|
||||
//
|
||||
// 将最左端(首部)的size个数据项移出数组,并返回该数据项。
|
||||
// PopLefts pops and returns <size> items from the beginning of array.
|
||||
func (a *IntArray) PopLefts(size int) []int {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -287,9 +250,7 @@ func (a *IntArray) PopLefts(size int) []int {
|
||||
return value
|
||||
}
|
||||
|
||||
// Pop <size> items from the end of array.
|
||||
//
|
||||
// 将最右端(尾部)的size个数据项移出数组,并返回该数据项
|
||||
// PopRights pops and returns <size> items from the end of array.
|
||||
func (a *IntArray) PopRights(size int) []int {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -302,11 +263,9 @@ func (a *IntArray) PopRights(size int) []int {
|
||||
return value
|
||||
}
|
||||
|
||||
// Get items by range, returns array[start:end].
|
||||
// Be aware that, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// Range picks and returns items by range, like array[start:end].
|
||||
// Notice, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// else a pointer to the underlying data.
|
||||
//
|
||||
// 将最右端(尾部)的size个数据项移出数组,并返回该数据项
|
||||
func (a *IntArray) Range(start, end int) []int {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -333,8 +292,6 @@ func (a *IntArray) Range(start, end int) []int {
|
||||
}
|
||||
|
||||
// See PushRight.
|
||||
//
|
||||
// 追加数据项, 等于: PushRight。
|
||||
func (a *IntArray) Append(value...int) *IntArray {
|
||||
a.mu.Lock()
|
||||
a.array = append(a.array, value...)
|
||||
@ -342,9 +299,7 @@ func (a *IntArray) Append(value...int) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Get the length of array.
|
||||
//
|
||||
// 数组长度。
|
||||
// Len returns the length of array.
|
||||
func (a *IntArray) Len() int {
|
||||
a.mu.RLock()
|
||||
length := len(a.array)
|
||||
@ -352,11 +307,9 @@ func (a *IntArray) Len() int {
|
||||
return length
|
||||
}
|
||||
|
||||
// Get the underlying data of array.
|
||||
// Be aware that, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// Slice returns the underlying data of array.
|
||||
// Notice, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// else a pointer to the underlying data.
|
||||
//
|
||||
// 返回原始数据数组.
|
||||
func (a *IntArray) Slice() []int {
|
||||
array := ([]int)(nil)
|
||||
if a.mu.IsSafe() {
|
||||
@ -370,9 +323,7 @@ func (a *IntArray) Slice() []int {
|
||||
return array
|
||||
}
|
||||
|
||||
// Return a new array, which is a copy of current array.
|
||||
//
|
||||
// 克隆当前数组,返回当前数组的一个拷贝。
|
||||
// Clone returns a new array, which is a copy of current array.
|
||||
func (a *IntArray) Clone() (newArray *IntArray) {
|
||||
a.mu.RLock()
|
||||
array := make([]int, len(a.array))
|
||||
@ -381,9 +332,7 @@ func (a *IntArray) Clone() (newArray *IntArray) {
|
||||
return NewIntArrayFrom(array, !a.mu.IsSafe())
|
||||
}
|
||||
|
||||
// Clear array.
|
||||
//
|
||||
// 清空数据数组。
|
||||
// Clear deletes all items of current array.
|
||||
func (a *IntArray) Clear() *IntArray {
|
||||
a.mu.Lock()
|
||||
if len(a.array) > 0 {
|
||||
@ -393,17 +342,13 @@ func (a *IntArray) Clear() *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Check whether a value exists in the array.
|
||||
//
|
||||
// 查找指定数值是否存在。
|
||||
// Contains checks whether a value exists in the array.
|
||||
func (a *IntArray) Contains(value int) bool {
|
||||
return a.Search(value) != -1
|
||||
}
|
||||
|
||||
|
||||
// Search array by <value>, returns the index of <value>, returns -1 if not exists.
|
||||
//
|
||||
// 查找指定数值的索引位置,返回索引位置,如果查找不到则返回-1。
|
||||
// Search searches array by <value>, returns the index of <value>,
|
||||
// or returns -1 if not exists.
|
||||
func (a *IntArray) Search(value int) int {
|
||||
if len(a.array) == 0 {
|
||||
return -1
|
||||
@ -421,9 +366,7 @@ func (a *IntArray) Search(value int) int {
|
||||
return result
|
||||
}
|
||||
|
||||
// Unique the array, clear repeated values.
|
||||
//
|
||||
// 清理数组中重复的元素项。
|
||||
// Unique uniques the array, clear repeated items.
|
||||
func (a *IntArray) Unique() *IntArray {
|
||||
a.mu.Lock()
|
||||
for i := 0; i < len(a.array) - 1; i++ {
|
||||
@ -437,9 +380,7 @@ func (a *IntArray) Unique() *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Lock writing by callback function f.
|
||||
//
|
||||
// 使用自定义方法执行加锁修改操作。
|
||||
// LockFunc locks writing by callback function <f>.
|
||||
func (a *IntArray) LockFunc(f func(array []int)) *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -447,9 +388,7 @@ func (a *IntArray) LockFunc(f func(array []int)) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Lock reading by callback function f.
|
||||
//
|
||||
// 使用自定义方法执行加锁读取操作。
|
||||
// RLockFunc locks reading by callback function <f>.
|
||||
func (a *IntArray) RLockFunc(f func(array []int)) *IntArray {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -457,11 +396,10 @@ func (a *IntArray) RLockFunc(f func(array []int)) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Merge two arrays. The parameter <array> can be any garray type or slice type.
|
||||
// Merge merges <array> into current array.
|
||||
// The parameter <array> can be any garray or slice type.
|
||||
// The difference between Merge and Append is Append supports only specified slice type,
|
||||
// but Merge supports more variable types.
|
||||
//
|
||||
// 合并两个数组, 支持任意的garray数组类型及slice类型.
|
||||
// but Merge supports more parameter types.
|
||||
func (a *IntArray) Merge(array interface{}) *IntArray {
|
||||
switch v := array.(type) {
|
||||
case *Array: a.Append(gconv.Ints(v.Slice())...)
|
||||
@ -476,10 +414,8 @@ func (a *IntArray) Merge(array interface{}) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Fills an array with num entries of the value of the value parameter,
|
||||
// keys starting at the startIndex parameter.
|
||||
//
|
||||
// 用value参数的值将数组填充num个条目,位置由startIndex参数指定的开始。
|
||||
// Fill fills an array with num entries of the value <value>,
|
||||
// keys starting at the <startIndex> parameter.
|
||||
func (a *IntArray) Fill(startIndex int, num int, value int) *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -496,10 +432,9 @@ func (a *IntArray) Fill(startIndex int, num int, value int) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Chunks an array into arrays with size elements.
|
||||
// Chunk splits an array into multiple arrays,
|
||||
// the size of each array is determined by <size>.
|
||||
// The last chunk may contain less than size elements.
|
||||
//
|
||||
// 将一个数组分割成多个数组,其中每个数组的单元数目由size决定。最后一个数组的单元数目可能会少于size个。
|
||||
func (a *IntArray) Chunk(size int) [][]int {
|
||||
if size < 1 {
|
||||
return nil
|
||||
@ -520,14 +455,10 @@ func (a *IntArray) Chunk(size int) [][]int {
|
||||
return n
|
||||
}
|
||||
|
||||
// Pad array to the specified length with a value.
|
||||
// Pad pads array to the specified length with <value>.
|
||||
// If size is positive then the array is padded on the right, or negative on the left.
|
||||
// If the absolute value of size is less than or equal to the length of the array
|
||||
// If the absolute value of <size> is less than or equal to the length of the array
|
||||
// then no padding takes place.
|
||||
//
|
||||
// 返回数组的一个拷贝,并用value将其填补到size指定的长度。
|
||||
// 如果size为正数,则填补到数组的右侧,如果为负数则从左侧开始填补。
|
||||
// 如果size的绝对值小于或等于数组的长度则没有任何填补。
|
||||
func (a *IntArray) Pad(size int, value int) *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -551,12 +482,9 @@ func (a *IntArray) Pad(size int, value int) *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Extract a slice of the array(If in concurrent safe usage,
|
||||
// it returns a copy of the slice; else a pointer).
|
||||
// It returns the sequence of elements from the array array as specified
|
||||
// by the offset and length parameters.
|
||||
//
|
||||
// 返回根据offset和size参数所指定的数组中的一段序列。
|
||||
// SubSlice returns a slice of elements from the array as specified
|
||||
// by the <offset> and <size> parameters.
|
||||
// If in concurrent safe usage, it returns a copy of the slice; else a pointer.
|
||||
func (a *IntArray) SubSlice(offset, size int) []int {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -575,18 +503,14 @@ func (a *IntArray) SubSlice(offset, size int) []int {
|
||||
}
|
||||
}
|
||||
|
||||
// Rand gets one random entry from array.
|
||||
//
|
||||
// 从数组中随机获得1个元素项(不删除)。
|
||||
// Rand randomly returns one item from array(no deleting).
|
||||
func (a *IntArray) Rand() int {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return a.array[grand.Intn(len(a.array))]
|
||||
}
|
||||
|
||||
// Rands gets one or more random entries from array(a copy).
|
||||
//
|
||||
// 从数组中随机拷贝size个元素项,构成slice返回。
|
||||
// Rands randomly returns <size> items from array(no deleting).
|
||||
func (a *IntArray) Rands(size int) []int {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -603,9 +527,7 @@ func (a *IntArray) Rands(size int) []int {
|
||||
return n
|
||||
}
|
||||
|
||||
// Randomly shuffles the array.
|
||||
//
|
||||
// 随机打乱当前数组。
|
||||
// Shuffle randomly shuffles the array.
|
||||
func (a *IntArray) Shuffle() *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -615,9 +537,7 @@ func (a *IntArray) Shuffle() *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Make array with elements in reverse order.
|
||||
//
|
||||
// 将当前数组反转。
|
||||
// Reverse makes array with elements in reverse order.
|
||||
func (a *IntArray) Reverse() *IntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -627,9 +547,7 @@ func (a *IntArray) Reverse() *IntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Join array elements with a string.
|
||||
//
|
||||
// 使用glue字符串串连当前数组的元素项,构造成新的字符串返回。
|
||||
// Join joins array elements with a string <glue>.
|
||||
func (a *IntArray) Join(glue string) string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -641,4 +559,22 @@ func (a *IntArray) Join(glue string) string {
|
||||
}
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// CountValues counts the number of occurrences of all values in the array.
|
||||
func (a *IntArray) CountValues() map[int]int {
|
||||
m := make(map[int]int)
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
for _, v := range a.array {
|
||||
m[v]++
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// String returns current array as a string.
|
||||
func (a *IntArray) String() string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return fmt.Sprint(a.array)
|
||||
}
|
||||
@ -17,15 +17,13 @@ import (
|
||||
)
|
||||
|
||||
type Array struct {
|
||||
mu *rwmutex.RWMutex // 互斥锁
|
||||
array []interface{} // 底层数组
|
||||
mu *rwmutex.RWMutex
|
||||
array []interface{}
|
||||
}
|
||||
|
||||
// Create an empty array.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 创建一个空的数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// New creates and returns an empty array.
|
||||
// The param <unsafe> used to specify whether using array in un-concurrent-safety,
|
||||
// which is false in default.
|
||||
func New(unsafe...bool) *Array {
|
||||
return NewArraySize(0, 0, unsafe...)
|
||||
}
|
||||
@ -35,11 +33,9 @@ func NewArray(unsafe...bool) *Array {
|
||||
return NewArraySize(0, 0, unsafe...)
|
||||
}
|
||||
|
||||
// Create an array with given size and cap.
|
||||
// NewArraySize create and returns an array with given size and cap.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 创建一个指定大小的数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewArraySize(size int, cap int, unsafe...bool) *Array {
|
||||
return &Array{
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -57,11 +53,9 @@ func NewFromCopy(array []interface{}, unsafe...bool) *Array {
|
||||
return NewArrayFromCopy(array, unsafe...)
|
||||
}
|
||||
|
||||
// Create an array with given slice <array>.
|
||||
// NewArrayFrom creates and returns an array with given slice <array>.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 通过给定的slice变量创建数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewArrayFrom(array []interface{}, unsafe...bool) *Array {
|
||||
return &Array{
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -69,11 +63,9 @@ func NewArrayFrom(array []interface{}, unsafe...bool) *Array {
|
||||
}
|
||||
}
|
||||
|
||||
// Create an array from a copy of given slice <array>.
|
||||
// NewArrayFromCopy creates and returns an array from a copy of given slice <array>.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 通过给定的slice拷贝创建数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewArrayFromCopy(array []interface{}, unsafe...bool) *Array {
|
||||
newArray := make([]interface{}, len(array))
|
||||
copy(newArray, array)
|
||||
@ -83,9 +75,8 @@ func NewArrayFromCopy(array []interface{}, unsafe...bool) *Array {
|
||||
}
|
||||
}
|
||||
|
||||
// Get value by index.
|
||||
//
|
||||
// 获取指定索引的数据项, 调用方注意判断数组边界
|
||||
// Get returns the value of the specified index,
|
||||
// the caller should notice the boundary of the array.
|
||||
func (a *Array) Get(index int) interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -93,9 +84,7 @@ func (a *Array) Get(index int) interface{} {
|
||||
return value
|
||||
}
|
||||
|
||||
// Set value by index.
|
||||
//
|
||||
// 设置指定索引的数据项, 调用方注意判断数组边界
|
||||
// Set sets value to specified index.
|
||||
func (a *Array) Set(index int, value interface{}) *Array {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -103,9 +92,7 @@ func (a *Array) Set(index int, value interface{}) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Set the underlying slice array with the given <array> param.
|
||||
//
|
||||
// 设置底层数组变量.
|
||||
// SetArray sets the underlying slice array with the given <array>.
|
||||
func (a *Array) SetArray(array []interface{}) *Array {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -113,9 +100,7 @@ func (a *Array) SetArray(array []interface{}) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Replace the array items by given <array> from the beginning of array.
|
||||
//
|
||||
// 使用指定数组替换到对应的索引元素值.
|
||||
// Replace replaces the array items by given <array> from the beginning of array.
|
||||
func (a *Array) Replace(array []interface{}) *Array {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -129,9 +114,7 @@ func (a *Array) Replace(array []interface{}) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Calculate the sum of values in an array.
|
||||
//
|
||||
// 对数组中的元素项求和(将元素值转换为int类型后叠加)。
|
||||
// Sum returns the sum of values in an array.
|
||||
func (a *Array) Sum() (sum int) {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -141,9 +124,7 @@ func (a *Array) Sum() (sum int) {
|
||||
return
|
||||
}
|
||||
|
||||
// Sort the array by custom function <less>.
|
||||
//
|
||||
// 使用自定义的排序函数将数组重新排序.
|
||||
// SortFunc sorts the array by custom function <less>.
|
||||
func (a *Array) SortFunc(less func(v1, v2 interface{}) bool) *Array {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -153,9 +134,7 @@ func (a *Array) SortFunc(less func(v1, v2 interface{}) bool) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Insert the <value> to the front of <index>.
|
||||
//
|
||||
// 在当前索引位置前插入一个数据项, 调用方注意判断数组边界。
|
||||
// InsertBefore inserts the <value> to the front of <index>.
|
||||
func (a *Array) InsertBefore(index int, value interface{}) *Array {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -165,9 +144,7 @@ func (a *Array) InsertBefore(index int, value interface{}) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Insert the <value> to the back of <index>.
|
||||
//
|
||||
// 在当前索引位置前插入一个数据项, 调用方注意判断数组边界。
|
||||
// InsertAfter inserts the <value> to the back of <index>.
|
||||
func (a *Array) InsertAfter(index int, value interface{}) *Array {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -177,13 +154,11 @@ func (a *Array) InsertAfter(index int, value interface{}) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Remove an item by index.
|
||||
//
|
||||
// 删除指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Remove removes an item by index.
|
||||
func (a *Array) Remove(index int) interface{} {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
// 边界删除判断,以提高删除效率
|
||||
// Determine array boundaries when deleting to improve deletion efficiency。
|
||||
if index == 0 {
|
||||
value := a.array[0]
|
||||
a.array = a.array[1 : ]
|
||||
@ -193,15 +168,15 @@ func (a *Array) Remove(index int) interface{} {
|
||||
a.array = a.array[: index]
|
||||
return value
|
||||
}
|
||||
// 如果非边界删除,会涉及到数组创建,那么删除的效率差一些
|
||||
// If it is a non-boundary delete,
|
||||
// it will involve the creation of an array,
|
||||
// then the deletion is less efficient.
|
||||
value := a.array[index]
|
||||
a.array = append(a.array[ : index], a.array[index + 1 : ]...)
|
||||
return value
|
||||
}
|
||||
|
||||
// Push new items to the beginning of array.
|
||||
//
|
||||
// 将数据项添加到数组的最左端(索引为0)。
|
||||
// PushLeft pushes one or multiple items to the beginning of array.
|
||||
func (a *Array) PushLeft(value...interface{}) *Array {
|
||||
a.mu.Lock()
|
||||
a.array = append(value, a.array...)
|
||||
@ -209,9 +184,8 @@ func (a *Array) PushLeft(value...interface{}) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Push new items to the end of array.
|
||||
//
|
||||
// 将数据项添加到数组的最右端(索引为length - 1), 等于: Append。
|
||||
// PushRight pushes one or multiple items to the end of array.
|
||||
// It equals to Append.
|
||||
func (a *Array) PushRight(value...interface{}) *Array {
|
||||
a.mu.Lock()
|
||||
a.array = append(a.array, value...)
|
||||
@ -219,16 +193,12 @@ func (a *Array) PushRight(value...interface{}) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// PopRand picks an random item out of array.
|
||||
//
|
||||
// 随机将一个数据项移出数组,并返回该数据项。
|
||||
// PopRand randomly pops and return an item out of array.
|
||||
func (a *Array) PopRand() interface{} {
|
||||
return a.Remove(grand.Intn(len(a.array)))
|
||||
}
|
||||
|
||||
// PopRands picks <size> items out of array.
|
||||
//
|
||||
// 随机将size个数据项移出数组,并返回该数据项。
|
||||
// PopRands randomly pops and returns <size> items out of array.
|
||||
func (a *Array) PopRands(size int) []interface{} {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -244,9 +214,7 @@ func (a *Array) PopRands(size int) []interface{} {
|
||||
return array
|
||||
}
|
||||
|
||||
// Pop an item from the beginning of array.
|
||||
//
|
||||
// 将最左端(索引为0)的数据项移出数组,并返回该数据项。
|
||||
// PopLeft pops and returns an item from the beginning of array.
|
||||
func (a *Array) PopLeft() interface{} {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -255,9 +223,7 @@ func (a *Array) PopLeft() interface{} {
|
||||
return value
|
||||
}
|
||||
|
||||
// Pop an item from the end of array.
|
||||
//
|
||||
// 将最右端(索引为length - 1)的数据项移出数组,并返回该数据项。
|
||||
// PopRight pops and returns an item from the end of array.
|
||||
func (a *Array) PopRight() interface{} {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -267,9 +233,7 @@ func (a *Array) PopRight() interface{} {
|
||||
return value
|
||||
}
|
||||
|
||||
// Pop <size> items from the beginning of array.
|
||||
//
|
||||
// 将最左端(首部)的size个数据项移出数组,并返回该数据项
|
||||
// PopLefts pops and returns <size> items from the beginning of array.
|
||||
func (a *Array) PopLefts(size int) []interface{} {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -282,9 +246,7 @@ func (a *Array) PopLefts(size int) []interface{} {
|
||||
return value
|
||||
}
|
||||
|
||||
// Pop <size> items from the end of array.
|
||||
//
|
||||
// 将最右端(尾部)的size个数据项移出数组,并返回该数据项
|
||||
// PopRights pops and returns <size> items from the end of array.
|
||||
func (a *Array) PopRights(size int) []interface{} {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -297,11 +259,9 @@ func (a *Array) PopRights(size int) []interface{} {
|
||||
return value
|
||||
}
|
||||
|
||||
// Get items by range, returns array[start:end].
|
||||
// Be aware that, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// Range picks and returns items by range, like array[start:end].
|
||||
// Notice, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// else a pointer to the underlying data.
|
||||
//
|
||||
// 将最右端(尾部)的size个数据项移出数组,并返回该数据项
|
||||
func (a *Array) Range(start, end int) []interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -328,16 +288,12 @@ func (a *Array) Range(start, end int) []interface{} {
|
||||
}
|
||||
|
||||
// See PushRight.
|
||||
//
|
||||
// 追加数据项, 等于: PushRight。
|
||||
func (a *Array) Append(value...interface{}) *Array {
|
||||
a.PushRight(value...)
|
||||
return a
|
||||
}
|
||||
|
||||
// Get the length of array.
|
||||
//
|
||||
// 数组长度。
|
||||
// Len returns the length of array.
|
||||
func (a *Array) Len() int {
|
||||
a.mu.RLock()
|
||||
length := len(a.array)
|
||||
@ -345,11 +301,9 @@ func (a *Array) Len() int {
|
||||
return length
|
||||
}
|
||||
|
||||
// Get the underlying data of array.
|
||||
// Be aware that, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// Slice returns the underlying data of array.
|
||||
// Notice, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// else a pointer to the underlying data.
|
||||
//
|
||||
// 返回原始数据数组.
|
||||
func (a *Array) Slice() []interface{} {
|
||||
array := ([]interface{})(nil)
|
||||
if a.mu.IsSafe() {
|
||||
@ -363,9 +317,7 @@ func (a *Array) Slice() []interface{} {
|
||||
return array
|
||||
}
|
||||
|
||||
// Return a new array, which is a copy of current array.
|
||||
//
|
||||
// 克隆当前数组,返回当前数组的一个拷贝。
|
||||
// Clone returns a new array, which is a copy of current array.
|
||||
func (a *Array) Clone() (newArray *Array) {
|
||||
a.mu.RLock()
|
||||
array := make([]interface{}, len(a.array))
|
||||
@ -374,9 +326,7 @@ func (a *Array) Clone() (newArray *Array) {
|
||||
return NewArrayFrom(array, !a.mu.IsSafe())
|
||||
}
|
||||
|
||||
// Clear array.
|
||||
//
|
||||
// 清空数据数组
|
||||
// Clear deletes all items of current array.
|
||||
func (a *Array) Clear() *Array {
|
||||
a.mu.Lock()
|
||||
if len(a.array) > 0 {
|
||||
@ -386,16 +336,13 @@ func (a *Array) Clear() *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Check whether a value exists in the array.
|
||||
//
|
||||
// 查找指定数值是否存在
|
||||
// Contains checks whether a value exists in the array.
|
||||
func (a *Array) Contains(value interface{}) bool {
|
||||
return a.Search(value) != -1
|
||||
}
|
||||
|
||||
// Search array by <value>, returns the index of <value>, returns -1 if not exists.
|
||||
//
|
||||
// 查找指定数值的索引位置,返回索引位置,如果查找不到则返回-1
|
||||
// Search searches array by <value>, returns the index of <value>,
|
||||
// or returns -1 if not exists.
|
||||
func (a *Array) Search(value interface{}) int {
|
||||
if len(a.array) == 0 {
|
||||
return -1
|
||||
@ -413,9 +360,7 @@ func (a *Array) Search(value interface{}) int {
|
||||
return result
|
||||
}
|
||||
|
||||
// Unique the array, clear repeated values.
|
||||
//
|
||||
// 清理数组中重复的元素项
|
||||
// Unique uniques the array, clear repeated items.
|
||||
func (a *Array) Unique() *Array {
|
||||
a.mu.Lock()
|
||||
for i := 0; i < len(a.array) - 1; i++ {
|
||||
@ -429,9 +374,7 @@ func (a *Array) Unique() *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Lock writing by callback function f.
|
||||
//
|
||||
// 使用自定义方法执行加锁修改操作
|
||||
// LockFunc locks writing by callback function <f>.
|
||||
func (a *Array) LockFunc(f func(array []interface{})) *Array {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -439,9 +382,7 @@ func (a *Array) LockFunc(f func(array []interface{})) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Lock reading by callback function f.
|
||||
//
|
||||
// 使用自定义方法执行加锁读取操作
|
||||
// RLockFunc locks reading by callback function <f>.
|
||||
func (a *Array) RLockFunc(f func(array []interface{})) *Array {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -449,11 +390,10 @@ func (a *Array) RLockFunc(f func(array []interface{})) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Merge two arrays. The parameter <array> can be any garray type or slice type.
|
||||
// Merge merges <array> into current array.
|
||||
// The parameter <array> can be any garray or slice type.
|
||||
// The difference between Merge and Append is Append supports only specified slice type,
|
||||
// but Merge supports more variable types.
|
||||
//
|
||||
// 合并两个数组, 支持任意的garray数组类型及slice类型.
|
||||
// but Merge supports more parameter types.
|
||||
func (a *Array) Merge(array interface{}) *Array {
|
||||
switch v := array.(type) {
|
||||
case *Array: a.Append(gconv.Interfaces(v.Slice())...)
|
||||
@ -468,10 +408,8 @@ func (a *Array) Merge(array interface{}) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Fills an array with num entries of the value of the value parameter,
|
||||
// keys starting at the start_index parameter.
|
||||
//
|
||||
// 用value参数的值将数组填充num个条目,位置由startIndex参数指定的开始。
|
||||
// Fill fills an array with num entries of the value <value>,
|
||||
// keys starting at the <startIndex> parameter.
|
||||
func (a *Array) Fill(startIndex int, num int, value interface{}) *Array {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -488,10 +426,9 @@ func (a *Array) Fill(startIndex int, num int, value interface{}) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Chunks an array into arrays with size elements.
|
||||
// Chunk splits an array into multiple arrays,
|
||||
// the size of each array is determined by <size>.
|
||||
// The last chunk may contain less than size elements.
|
||||
//
|
||||
// 将一个数组分割成多个数组,其中每个数组的单元数目由size决定。最后一个数组的单元数目可能会少于size个。
|
||||
func (a *Array) Chunk(size int) [][]interface{} {
|
||||
if size < 1 {
|
||||
return nil
|
||||
@ -512,15 +449,10 @@ func (a *Array) Chunk(size int) [][]interface{} {
|
||||
return n
|
||||
}
|
||||
|
||||
// Pad array to the specified length with a value.
|
||||
// If size is positive then the array is padded on the right,
|
||||
// if it's negative then on the left.
|
||||
// If the absolute value of size is less than or equal to the length of the array
|
||||
// Pad pads array to the specified length with <value>.
|
||||
// If size is positive then the array is padded on the right, or negative on the left.
|
||||
// If the absolute value of <size> is less than or equal to the length of the array
|
||||
// then no padding takes place.
|
||||
//
|
||||
// 返回数组的一个拷贝,并用value将其填补到size指定的长度。
|
||||
// 如果size为正数,则填补到数组的右侧,如果为负数则从左侧开始填补。
|
||||
// 如果size的绝对值小于或等于数组的长度则没有任何填补。
|
||||
func (a *Array) Pad(size int, val interface{}) *Array {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -544,10 +476,9 @@ func (a *Array) Pad(size int, val interface{}) *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Extract a slice of the array(If in concurrent safe usage, it returns a copy of the slice; else a pointer).
|
||||
// It returns the sequence of elements from the array array as specified by the offset and length parameters.
|
||||
//
|
||||
// 返回根据offset和size参数所指定的数组中的一段序列。
|
||||
// SubSlice returns a slice of elements from the array as specified
|
||||
// by the <offset> and <size> parameters.
|
||||
// If in concurrent safe usage, it returns a copy of the slice; else a pointer.
|
||||
func (a *Array) SubSlice(offset, size int) []interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -566,18 +497,14 @@ func (a *Array) SubSlice(offset, size int) []interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
// Rand gets one random entry from array.
|
||||
//
|
||||
// 从数组中随机获得1个元素项(不删除)。
|
||||
// Rand randomly returns one item from array(no deleting).
|
||||
func (a *Array) Rand() interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return a.array[grand.Intn(len(a.array))]
|
||||
}
|
||||
|
||||
// Rands gets one or more random entries from array(a copy).
|
||||
//
|
||||
// 从数组中随机拷贝size个元素项,构成slice返回。
|
||||
// Rands randomly returns <size> items from array(no deleting).
|
||||
func (a *Array) Rands(size int) []interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -594,9 +521,7 @@ func (a *Array) Rands(size int) []interface{} {
|
||||
return n
|
||||
}
|
||||
|
||||
// Randomly shuffles the array.
|
||||
//
|
||||
// 随机打乱当前数组。
|
||||
// Shuffle randomly shuffles the array.
|
||||
func (a *Array) Shuffle() *Array {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -606,9 +531,7 @@ func (a *Array) Shuffle() *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Make array with elements in reverse order.
|
||||
//
|
||||
// 将当前数组反转。
|
||||
// Reverse makes array with elements in reverse order.
|
||||
func (a *Array) Reverse() *Array {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -618,9 +541,7 @@ func (a *Array) Reverse() *Array {
|
||||
return a
|
||||
}
|
||||
|
||||
// Join array elements with a string.
|
||||
//
|
||||
// 使用glue字符串串连当前数组的元素项,构造成新的字符串返回。
|
||||
// Join joins array elements with a string <glue>.
|
||||
func (a *Array) Join(glue string) string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -634,9 +555,7 @@ func (a *Array) Join(glue string) string {
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// Counts all the values of an array.
|
||||
//
|
||||
// 统计数组中所有的值出现的次数.
|
||||
// CountValues counts the number of occurrences of all values in the array.
|
||||
func (a *Array) CountValues() map[interface{}]int {
|
||||
m := make(map[interface{}]int)
|
||||
a.mu.RLock()
|
||||
@ -648,8 +567,6 @@ func (a *Array) CountValues() map[interface{}]int {
|
||||
}
|
||||
|
||||
// String returns current array as a string.
|
||||
//
|
||||
// 将当前数组转换为字符串返回。
|
||||
func (a *Array) String() string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
|
||||
@ -8,7 +8,8 @@ package garray
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/gogf/gf/g/internal/rwmutex"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/g/internal/rwmutex"
|
||||
"github.com/gogf/gf/g/util/gconv"
|
||||
"github.com/gogf/gf/g/util/grand"
|
||||
"math"
|
||||
@ -17,24 +18,20 @@ import (
|
||||
)
|
||||
|
||||
type StringArray struct {
|
||||
mu *rwmutex.RWMutex // 互斥锁
|
||||
array []string // 底层数组
|
||||
mu *rwmutex.RWMutex
|
||||
array []string
|
||||
}
|
||||
|
||||
// Create an empty array.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 创建一个空的数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// NewStringArray creates and returns an empty array.
|
||||
// The param <unsafe> used to specify whether using array in un-concurrent-safety,
|
||||
// which is false in default.
|
||||
func NewStringArray(unsafe...bool) *StringArray {
|
||||
return NewStringArraySize(0, 0, unsafe...)
|
||||
}
|
||||
|
||||
// Create an array with given size and cap.
|
||||
// NewStringArraySize create and returns an array with given size and cap.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 创建一个指定大小的数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewStringArraySize(size int, cap int, unsafe...bool) *StringArray {
|
||||
return &StringArray{
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -42,11 +39,9 @@ func NewStringArraySize(size int, cap int, unsafe...bool) *StringArray {
|
||||
}
|
||||
}
|
||||
|
||||
// Create an array with given slice <array>.
|
||||
// NewStringArrayFrom creates and returns an array with given slice <array>.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 通过给定的slice变量创建数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewStringArrayFrom(array []string, unsafe...bool) *StringArray {
|
||||
return &StringArray {
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -54,11 +49,9 @@ func NewStringArrayFrom(array []string, unsafe...bool) *StringArray {
|
||||
}
|
||||
}
|
||||
|
||||
// Create an array from a copy of given slice <array>.
|
||||
// NewStringArrayFromCopy creates and returns an array from a copy of given slice <array>.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 通过给定的slice拷贝创建数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewStringArrayFromCopy(array []string, unsafe...bool) *StringArray {
|
||||
newArray := make([]string, len(array))
|
||||
copy(newArray, array)
|
||||
@ -68,9 +61,8 @@ func NewStringArrayFromCopy(array []string, unsafe...bool) *StringArray {
|
||||
}
|
||||
}
|
||||
|
||||
// Get value by index.
|
||||
//
|
||||
// 获取指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Get returns the value of the specified index,
|
||||
// the caller should notice the boundary of the array.
|
||||
func (a *StringArray) Get(index int) string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -78,9 +70,7 @@ func (a *StringArray) Get(index int) string {
|
||||
return value
|
||||
}
|
||||
|
||||
// Set value by index.
|
||||
//
|
||||
// 设置指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Set sets value to specified index.
|
||||
func (a *StringArray) Set(index int, value string) *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -88,9 +78,7 @@ func (a *StringArray) Set(index int, value string) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Set the underlying slice array with the given <array> param.
|
||||
//
|
||||
// 设置底层数组变量.
|
||||
// SetArray sets the underlying slice array with the given <array>.
|
||||
func (a *StringArray) SetArray(array []string) *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -98,9 +86,7 @@ func (a *StringArray) SetArray(array []string) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Replace the array items by given <array> from the beginning of array.
|
||||
//
|
||||
// 使用指定数组替换到对应的索引元素值.
|
||||
// Replace replaces the array items by given <array> from the beginning of array.
|
||||
func (a *StringArray) Replace(array []string) *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -114,9 +100,7 @@ func (a *StringArray) Replace(array []string) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Calculate the sum of values in an array.
|
||||
//
|
||||
// 对数组中的元素项求和(将元素值转换为int类型后叠加)。
|
||||
// Sum returns the sum of values in an array.
|
||||
func (a *StringArray) Sum() (sum int) {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -126,11 +110,9 @@ func (a *StringArray) Sum() (sum int) {
|
||||
return
|
||||
}
|
||||
|
||||
// Sort the array in increasing order.
|
||||
// Sort sorts the array in increasing order.
|
||||
// The param <reverse> controls whether sort
|
||||
// in increasing order(default) or decreasing order
|
||||
//
|
||||
// 将数组排序(默认从低到高).
|
||||
func (a *StringArray) Sort(reverse...bool) *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -147,9 +129,7 @@ func (a *StringArray) Sort(reverse...bool) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Sort the array by custom function <less>.
|
||||
//
|
||||
// 使用自定义的排序函数将数组重新排序.
|
||||
// SortFunc sorts the array by custom function <less>.
|
||||
func (a *StringArray) SortFunc(less func(v1, v2 string) bool) *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -159,9 +139,7 @@ func (a *StringArray) SortFunc(less func(v1, v2 string) bool) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Insert the <value> to the front of <index>.
|
||||
//
|
||||
// 在当前索引位置前插入一个数据项, 调用方注意判断数组边界。
|
||||
// InsertBefore inserts the <value> to the front of <index>.
|
||||
func (a *StringArray) InsertBefore(index int, value string) *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -171,9 +149,7 @@ func (a *StringArray) InsertBefore(index int, value string) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Insert the <value> to the back of <index>.
|
||||
//
|
||||
// 在当前索引位置前插入一个数据项, 调用方注意判断数组边界。
|
||||
// InsertAfter inserts the <value> to the back of <index>.
|
||||
func (a *StringArray) InsertAfter(index int, value string) *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -183,13 +159,11 @@ func (a *StringArray) InsertAfter(index int, value string) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Remove an item by index.
|
||||
//
|
||||
// 删除指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Remove removes an item by index.
|
||||
func (a *StringArray) Remove(index int) string {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
// 边界删除判断,以提高删除效率
|
||||
// Determine array boundaries when deleting to improve deletion efficiency。
|
||||
if index == 0 {
|
||||
value := a.array[0]
|
||||
a.array = a.array[1 : ]
|
||||
@ -199,15 +173,15 @@ func (a *StringArray) Remove(index int) string {
|
||||
a.array = a.array[: index]
|
||||
return value
|
||||
}
|
||||
// 如果非边界删除,会涉及到数组创建,那么删除的效率差一些
|
||||
// If it is a non-boundary delete,
|
||||
// it will involve the creation of an array,
|
||||
// then the deletion is less efficient.
|
||||
value := a.array[index]
|
||||
a.array = append(a.array[ : index], a.array[index + 1 : ]...)
|
||||
return value
|
||||
}
|
||||
|
||||
// Push new items to the beginning of array.
|
||||
//
|
||||
// 将数据项添加到数组的最左端(索引为0)。
|
||||
// PushLeft pushes one or multiple items to the beginning of array.
|
||||
func (a *StringArray) PushLeft(value...string) *StringArray {
|
||||
a.mu.Lock()
|
||||
a.array = append(value, a.array...)
|
||||
@ -215,9 +189,8 @@ func (a *StringArray) PushLeft(value...string) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Push new items to the end of array.
|
||||
//
|
||||
// 将数据项添加到数组的最右端(索引为length - 1), 等于: Append。
|
||||
// PushRight pushes one or multiple items to the end of array.
|
||||
// It equals to Append.
|
||||
func (a *StringArray) PushRight(value...string) *StringArray {
|
||||
a.mu.Lock()
|
||||
a.array = append(a.array, value...)
|
||||
@ -225,9 +198,7 @@ func (a *StringArray) PushRight(value...string) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Pop an item from the beginning of array.
|
||||
//
|
||||
// 将最左端(索引为0)的数据项移出数组,并返回该数据项。
|
||||
// PopLeft pops and returns an item from the beginning of array.
|
||||
func (a *StringArray) PopLeft() string {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -236,9 +207,7 @@ func (a *StringArray) PopLeft() string {
|
||||
return value
|
||||
}
|
||||
|
||||
// Pop an item from the end of array.
|
||||
//
|
||||
// 将最右端(索引为length - 1)的数据项移出数组,并返回该数据项。
|
||||
// PopRight pops and returns an item from the end of array.
|
||||
func (a *StringArray) PopRight() string {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -248,16 +217,12 @@ func (a *StringArray) PopRight() string {
|
||||
return value
|
||||
}
|
||||
|
||||
// PopRand picks an random item out of array.
|
||||
//
|
||||
// 随机将一个数据项移出数组,并返回该数据项。
|
||||
// PopRand randomly pops and return an item out of array.
|
||||
func (a *StringArray) PopRand() string {
|
||||
return a.Remove(grand.Intn(len(a.array)))
|
||||
}
|
||||
|
||||
// PopRands picks <size> items out of array.
|
||||
//
|
||||
// 随机将size个数据项移出数组,并返回该数据项。
|
||||
// PopRands randomly pops and returns <size> items out of array.
|
||||
func (a *StringArray) PopRands(size int) []string {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -273,9 +238,7 @@ func (a *StringArray) PopRands(size int) []string {
|
||||
return array
|
||||
}
|
||||
|
||||
// Pop <size> items from the beginning of array.
|
||||
//
|
||||
// 将最左端(首部)的size个数据项移出数组,并返回该数据项
|
||||
// PopLefts pops and returns <size> items from the beginning of array.
|
||||
func (a *StringArray) PopLefts(size int) []string {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -288,9 +251,7 @@ func (a *StringArray) PopLefts(size int) []string {
|
||||
return value
|
||||
}
|
||||
|
||||
// Pop <size> items from the end of array.
|
||||
//
|
||||
// 将最右端(尾部)的size个数据项移出数组,并返回该数据项
|
||||
// PopRights pops and returns <size> items from the end of array.
|
||||
func (a *StringArray) PopRights(size int) []string {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -303,11 +264,9 @@ func (a *StringArray) PopRights(size int) []string {
|
||||
return value
|
||||
}
|
||||
|
||||
// Get items by range, returns array[start:end].
|
||||
// Be aware that, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// Range picks and returns items by range, like array[start:end].
|
||||
// Notice, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// else a pointer to the underlying data.
|
||||
//
|
||||
// 将最右端(尾部)的size个数据项移出数组,并返回该数据项
|
||||
func (a *StringArray) Range(start, end int) []string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -334,8 +293,6 @@ func (a *StringArray) Range(start, end int) []string {
|
||||
}
|
||||
|
||||
// See PushRight.
|
||||
//
|
||||
// 追加数据项, 等于: PushRight。
|
||||
func (a *StringArray) Append(value...string) *StringArray {
|
||||
a.mu.Lock()
|
||||
a.array = append(a.array, value...)
|
||||
@ -343,9 +300,7 @@ func (a *StringArray) Append(value...string) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Get the length of array.
|
||||
//
|
||||
// 数组长度。
|
||||
// Len returns the length of array.
|
||||
func (a *StringArray) Len() int {
|
||||
a.mu.RLock()
|
||||
length := len(a.array)
|
||||
@ -353,11 +308,9 @@ func (a *StringArray) Len() int {
|
||||
return length
|
||||
}
|
||||
|
||||
// Get the underlying data of array.
|
||||
// Be aware that, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// Slice returns the underlying data of array.
|
||||
// Notice, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// else a pointer to the underlying data.
|
||||
//
|
||||
// 返回原始数据数组.
|
||||
func (a *StringArray) Slice() []string {
|
||||
array := ([]string)(nil)
|
||||
if a.mu.IsSafe() {
|
||||
@ -371,9 +324,7 @@ func (a *StringArray) Slice() []string {
|
||||
return array
|
||||
}
|
||||
|
||||
// Return a new array, which is a copy of current array.
|
||||
//
|
||||
// 克隆当前数组,返回当前数组的一个拷贝。
|
||||
// Clone returns a new array, which is a copy of current array.
|
||||
func (a *StringArray) Clone() (newArray *StringArray) {
|
||||
a.mu.RLock()
|
||||
array := make([]string, len(a.array))
|
||||
@ -382,9 +333,7 @@ func (a *StringArray) Clone() (newArray *StringArray) {
|
||||
return NewStringArrayFrom(array, !a.mu.IsSafe())
|
||||
}
|
||||
|
||||
// Clear array.
|
||||
//
|
||||
// 清空数据数组。
|
||||
// Clear deletes all items of current array.
|
||||
func (a *StringArray) Clear() *StringArray {
|
||||
a.mu.Lock()
|
||||
if len(a.array) > 0 {
|
||||
@ -394,16 +343,13 @@ func (a *StringArray) Clear() *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Check whether a value exists in the array.
|
||||
//
|
||||
// 查找指定数值是否存在。
|
||||
// Contains checks whether a value exists in the array.
|
||||
func (a *StringArray) Contains(value string) bool {
|
||||
return a.Search(value) != -1
|
||||
}
|
||||
|
||||
// Search array by <value>, returns the index of <value>, returns -1 if not exists.
|
||||
//
|
||||
// 查找指定数值的索引位置,返回索引位置,如果查找不到则返回-1。
|
||||
// Search searches array by <value>, returns the index of <value>,
|
||||
// or returns -1 if not exists.
|
||||
func (a *StringArray) Search(value string) int {
|
||||
if len(a.array) == 0 {
|
||||
return -1
|
||||
@ -420,9 +366,7 @@ func (a *StringArray) Search(value string) int {
|
||||
return result
|
||||
}
|
||||
|
||||
// Unique the array, clear repeated values.
|
||||
//
|
||||
// 清理数组中重复的元素项。
|
||||
// Unique uniques the array, clear repeated items.
|
||||
func (a *StringArray) Unique() *StringArray {
|
||||
a.mu.Lock()
|
||||
for i := 0; i < len(a.array) - 1; i++ {
|
||||
@ -436,9 +380,7 @@ func (a *StringArray) Unique() *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Lock writing by callback function f.
|
||||
//
|
||||
// 使用自定义方法执行加锁修改操作。
|
||||
// LockFunc locks writing by callback function <f>.
|
||||
func (a *StringArray) LockFunc(f func(array []string)) *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -446,9 +388,7 @@ func (a *StringArray) LockFunc(f func(array []string)) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Lock reading by callback function f.
|
||||
//
|
||||
// 使用自定义方法执行加锁读取操作。
|
||||
// RLockFunc locks reading by callback function <f>.
|
||||
func (a *StringArray) RLockFunc(f func(array []string)) *StringArray {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -456,11 +396,10 @@ func (a *StringArray) RLockFunc(f func(array []string)) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Merge two arrays. The parameter <array> can be any garray type or slice type.
|
||||
// Merge merges <array> into current array.
|
||||
// The parameter <array> can be any garray or slice type.
|
||||
// The difference between Merge and Append is Append supports only specified slice type,
|
||||
// but Merge supports more variable types.
|
||||
//
|
||||
// 合并两个数组, 支持任意的garray数组类型及slice类型.
|
||||
// but Merge supports more parameter types.
|
||||
func (a *StringArray) Merge(array interface{}) *StringArray {
|
||||
switch v := array.(type) {
|
||||
case *Array: a.Append(gconv.Strings(v.Slice())...)
|
||||
@ -475,10 +414,8 @@ func (a *StringArray) Merge(array interface{}) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Fills an array with num entries of the value of the value parameter,
|
||||
// keys starting at the start_index parameter.
|
||||
//
|
||||
// 用value参数的值将数组填充num个条目,位置由startIndex参数指定的开始。
|
||||
// Fill fills an array with num entries of the value <value>,
|
||||
// keys starting at the <startIndex> parameter.
|
||||
func (a *StringArray) Fill(startIndex int, num int, value string) *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -495,10 +432,9 @@ func (a *StringArray) Fill(startIndex int, num int, value string) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Chunks an array into arrays with size elements.
|
||||
// Chunk splits an array into multiple arrays,
|
||||
// the size of each array is determined by <size>.
|
||||
// The last chunk may contain less than size elements.
|
||||
//
|
||||
// 将一个数组分割成多个数组,其中每个数组的单元数目由size决定。最后一个数组的单元数目可能会少于size个。
|
||||
func (a *StringArray) Chunk(size int) [][]string {
|
||||
if size < 1 {
|
||||
return nil
|
||||
@ -519,15 +455,10 @@ func (a *StringArray) Chunk(size int) [][]string {
|
||||
return n
|
||||
}
|
||||
|
||||
// Pad array to the specified length with a value.
|
||||
// If size is positive then the array is padded on the right,
|
||||
// if it's negative then on the left.
|
||||
// If the absolute value of size is less than or equal to the length of the array
|
||||
// Pad pads array to the specified length with <value>.
|
||||
// If size is positive then the array is padded on the right, or negative on the left.
|
||||
// If the absolute value of <size> is less than or equal to the length of the array
|
||||
// then no padding takes place.
|
||||
//
|
||||
// 返回数组的一个拷贝,并用value将其填补到size指定的长度。
|
||||
// 如果size为正数,则填补到数组的右侧,如果为负数则从左侧开始填补。
|
||||
// 如果size的绝对值小于或等于数组的长度则没有任何填补。
|
||||
func (a *StringArray) Pad(size int, value string) *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -551,12 +482,9 @@ func (a *StringArray) Pad(size int, value string) *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Extract a slice of the array(If in concurrent safe usage,
|
||||
// it returns a copy of the slice; else a pointer).
|
||||
// It returns the sequence of elements from the array array as specified
|
||||
// by the offset and length parameters.
|
||||
//
|
||||
// 返回根据offset和size参数所指定的数组中的一段序列。
|
||||
// SubSlice returns a slice of elements from the array as specified
|
||||
// by the <offset> and <size> parameters.
|
||||
// If in concurrent safe usage, it returns a copy of the slice; else a pointer.
|
||||
func (a *StringArray) SubSlice(offset, size int) []string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -575,18 +503,14 @@ func (a *StringArray) SubSlice(offset, size int) []string {
|
||||
}
|
||||
}
|
||||
|
||||
// Rand gets one random entry from array.
|
||||
//
|
||||
// 从数组中随机获得1个元素项(不删除)。
|
||||
// Rand randomly returns one item from array(no deleting).
|
||||
func (a *StringArray) Rand() string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return a.array[grand.Intn(len(a.array))]
|
||||
}
|
||||
|
||||
// Rands gets one or more random entries from array(a copy).
|
||||
//
|
||||
// 从数组中随机拷贝size个元素项,构成slice返回。
|
||||
// Rands randomly returns <size> items from array(no deleting).
|
||||
func (a *StringArray) Rands(size int) []string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -603,9 +527,7 @@ func (a *StringArray) Rands(size int) []string {
|
||||
return n
|
||||
}
|
||||
|
||||
// Randomly shuffles the array.
|
||||
//
|
||||
// 随机打乱当前数组。
|
||||
// Shuffle randomly shuffles the array.
|
||||
func (a *StringArray) Shuffle() *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -615,9 +537,7 @@ func (a *StringArray) Shuffle() *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Make array with elements in reverse order.
|
||||
//
|
||||
// 将当前数组反转。
|
||||
// Reverse makes array with elements in reverse order.
|
||||
func (a *StringArray) Reverse() *StringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -627,9 +547,7 @@ func (a *StringArray) Reverse() *StringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Join array elements with a string.
|
||||
//
|
||||
// 使用glue字符串串连当前数组的元素项,构造成新的字符串返回。
|
||||
// Join joins array elements with a string <glue>.
|
||||
func (a *StringArray) Join(glue string) string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -643,3 +561,20 @@ func (a *StringArray) Join(glue string) string {
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// CountValues counts the number of occurrences of all values in the array.
|
||||
func (a *StringArray) CountValues() map[string]int {
|
||||
m := make(map[string]int)
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
for _, v := range a.array {
|
||||
m[v]++
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// String returns current array as a string.
|
||||
func (a *StringArray) String() string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return fmt.Sprint(a.array)
|
||||
}
|
||||
|
||||
@ -8,7 +8,8 @@ package garray
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/gogf/gf/g/container/gtype"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/g/container/gtype"
|
||||
"github.com/gogf/gf/g/internal/rwmutex"
|
||||
"github.com/gogf/gf/g/util/gconv"
|
||||
"github.com/gogf/gf/g/util/grand"
|
||||
@ -16,28 +17,24 @@ import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// 默认按照从小到大进行排序
|
||||
// It's using increasing order in default.
|
||||
type SortedIntArray struct {
|
||||
mu *rwmutex.RWMutex // 互斥锁
|
||||
array []int // 底层数组
|
||||
unique *gtype.Bool // 是否要求不能重复(默认false)
|
||||
compareFunc func(v1, v2 int) int // 比较函数,返回值 -1: v1 < v2;0: v1 == v2;1: v1 > v2
|
||||
mu *rwmutex.RWMutex
|
||||
array []int
|
||||
unique *gtype.Bool // Whether enable unique feature(false)
|
||||
compareFunc func(v1, v2 int) int // Comparison function(it returns -1: v1 < v2; 0: v1 == v2; 1: v1 > v2)
|
||||
}
|
||||
|
||||
// Create an empty sorted array.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 创建一个空的排序数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// NewSortedIntArray creates and returns an empty sorted array.
|
||||
// The param <unsafe> used to specify whether using array in un-concurrent-safety,
|
||||
// which is false in default.
|
||||
func NewSortedIntArray(unsafe...bool) *SortedIntArray {
|
||||
return NewSortedIntArraySize(0, unsafe...)
|
||||
}
|
||||
|
||||
// Create a sorted array with given size and cap.
|
||||
// NewSortedIntArraySize create and returns an sorted array with given size and cap.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 创建一个指定大小的排序数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewSortedIntArraySize(cap int, unsafe...bool) *SortedIntArray {
|
||||
return &SortedIntArray {
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -55,11 +52,9 @@ func NewSortedIntArraySize(cap int, unsafe...bool) *SortedIntArray {
|
||||
}
|
||||
}
|
||||
|
||||
// Create an array with given slice <array>.
|
||||
// NewIntArrayFrom creates and returns an sorted array with given slice <array>.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 通过给定的slice变量创建排序数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewSortedIntArrayFrom(array []int, unsafe...bool) *SortedIntArray {
|
||||
a := NewSortedIntArraySize(0, unsafe...)
|
||||
a.array = array
|
||||
@ -67,11 +62,9 @@ func NewSortedIntArrayFrom(array []int, unsafe...bool) *SortedIntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Create an array from a copy of given slice <array>.
|
||||
// NewSortedIntArrayFromCopy creates and returns an sorted array from a copy of given slice <array>.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 通过给定的slice拷贝创建数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewSortedIntArrayFromCopy(array []int, unsafe...bool) *SortedIntArray {
|
||||
newArray := make([]int, len(array))
|
||||
copy(newArray, array)
|
||||
@ -81,9 +74,7 @@ func NewSortedIntArrayFromCopy(array []int, unsafe...bool) *SortedIntArray {
|
||||
}
|
||||
}
|
||||
|
||||
// Set the underlying slice array with the given <array> param.
|
||||
//
|
||||
// 设置底层数组变量.
|
||||
// SetArray sets the underlying slice array with the given <array>.
|
||||
func (a *SortedIntArray) SetArray(array []int) *SortedIntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -92,9 +83,9 @@ func (a *SortedIntArray) SetArray(array []int) *SortedIntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Sort the array in increasing order.
|
||||
//
|
||||
// 将数组排序(默认从低到高).
|
||||
// Sort sorts the array in increasing order.
|
||||
// The param <reverse> controls whether sort
|
||||
// in increasing order(default) or decreasing order.
|
||||
func (a *SortedIntArray) Sort() *SortedIntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -102,9 +93,7 @@ func (a *SortedIntArray) Sort() *SortedIntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// And values to sorted array, the array always keeps sorted.
|
||||
//
|
||||
// 添加数据项.
|
||||
// Add adds one or multiple values to sorted array, the array always keeps sorted.
|
||||
func (a *SortedIntArray) Add(values...int) *SortedIntArray {
|
||||
if len(values) == 0 {
|
||||
return a
|
||||
@ -120,7 +109,6 @@ func (a *SortedIntArray) Add(values...int) *SortedIntArray {
|
||||
a.array = append(a.array, value)
|
||||
continue
|
||||
}
|
||||
// 加到指定索引后面
|
||||
if cmp > 0 {
|
||||
index++
|
||||
}
|
||||
@ -131,9 +119,8 @@ func (a *SortedIntArray) Add(values...int) *SortedIntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Get value by index.
|
||||
//
|
||||
// 获取指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Get returns the value of the specified index,
|
||||
// the caller should notice the boundary of the array.
|
||||
func (a *SortedIntArray) Get(index int) int {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -141,13 +128,11 @@ func (a *SortedIntArray) Get(index int) int {
|
||||
return value
|
||||
}
|
||||
|
||||
// Remove an item by index.
|
||||
//
|
||||
// 删除指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Remove removes an item by index.
|
||||
func (a *SortedIntArray) Remove(index int) int {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
// 边界删除判断,以提高删除效率
|
||||
// Determine array boundaries when deleting to improve deletion efficiency.
|
||||
if index == 0 {
|
||||
value := a.array[0]
|
||||
a.array = a.array[1 : ]
|
||||
@ -157,15 +142,15 @@ func (a *SortedIntArray) Remove(index int) int {
|
||||
a.array = a.array[: index]
|
||||
return value
|
||||
}
|
||||
// 如果非边界删除,会涉及到数组创建,那么删除的效率差一些
|
||||
// If it is a non-boundary delete,
|
||||
// it will involve the creation of an array,
|
||||
// then the deletion is less efficient.
|
||||
value := a.array[index]
|
||||
a.array = append(a.array[ : index], a.array[index + 1 : ]...)
|
||||
return value
|
||||
}
|
||||
|
||||
// Push new items to the beginning of array.
|
||||
//
|
||||
// 将数据项添加到数组的最左端(索引为0)。
|
||||
// PopLeft pops and returns an item from the beginning of array.
|
||||
func (a *SortedIntArray) PopLeft() int {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -174,9 +159,7 @@ func (a *SortedIntArray) PopLeft() int {
|
||||
return value
|
||||
}
|
||||
|
||||
// Push new items to the end of array.
|
||||
//
|
||||
// 将数据项添加到数组的最右端(索引为length - 1)。
|
||||
// PopRight pops and returns an item from the end of array.
|
||||
func (a *SortedIntArray) PopRight() int {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -186,16 +169,12 @@ func (a *SortedIntArray) PopRight() int {
|
||||
return value
|
||||
}
|
||||
|
||||
// PopRand picks an random item out of array.
|
||||
//
|
||||
// 随机将一个数据项移出数组,并返回该数据项。
|
||||
// PopRand randomly pops and return an item out of array.
|
||||
func (a *SortedIntArray) PopRand() int {
|
||||
return a.Remove(grand.Intn(len(a.array)))
|
||||
}
|
||||
|
||||
// PopRands picks <size> items out of array.
|
||||
//
|
||||
// 随机将size个数据项移出数组,并返回该数据项。
|
||||
// PopRands randomly pops and returns <size> items out of array.
|
||||
func (a *SortedIntArray) PopRands(size int) []int {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -211,9 +190,7 @@ func (a *SortedIntArray) PopRands(size int) []int {
|
||||
return array
|
||||
}
|
||||
|
||||
// Pop <size> items from the beginning of array.
|
||||
//
|
||||
// 将最左端(首部)的size个数据项移出数组,并返回该数据项
|
||||
// PopLefts pops and returns <size> items from the beginning of array.
|
||||
func (a *SortedIntArray) PopLefts(size int) []int {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -226,9 +203,7 @@ func (a *SortedIntArray) PopLefts(size int) []int {
|
||||
return value
|
||||
}
|
||||
|
||||
// Pop <size> items from the end of array.
|
||||
//
|
||||
// 将最右端(尾部)的size个数据项移出数组,并返回该数据项
|
||||
// PopRights pops and returns <size> items from the end of array.
|
||||
func (a *SortedIntArray) PopRights(size int) []int {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -241,11 +216,9 @@ func (a *SortedIntArray) PopRights(size int) []int {
|
||||
return value
|
||||
}
|
||||
|
||||
// Get items by range, returns array[start:end].
|
||||
// Be aware that, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// Range picks and returns items by range, like array[start:end].
|
||||
// Notice, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// else a pointer to the underlying data.
|
||||
//
|
||||
// 将最右端(尾部)的size个数据项移出数组,并返回该数据项
|
||||
func (a *SortedIntArray) Range(start, end int) []int {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -271,9 +244,7 @@ func (a *SortedIntArray) Range(start, end int) []int {
|
||||
return array
|
||||
}
|
||||
|
||||
// Get the length of array.
|
||||
//
|
||||
// 数组长度。
|
||||
// Len returns the length of array.
|
||||
func (a *SortedIntArray) Len() int {
|
||||
a.mu.RLock()
|
||||
length := len(a.array)
|
||||
@ -281,9 +252,7 @@ func (a *SortedIntArray) Len() int {
|
||||
return length
|
||||
}
|
||||
|
||||
// Calculate the sum of values in an array.
|
||||
//
|
||||
// 对数组中的元素项求和。
|
||||
// Sum returns the sum of values in an array.
|
||||
func (a *SortedIntArray) Sum() (sum int) {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -293,11 +262,9 @@ func (a *SortedIntArray) Sum() (sum int) {
|
||||
return
|
||||
}
|
||||
|
||||
// Get the underlying data of array.
|
||||
// Be aware that, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// Slice returns the underlying data of array.
|
||||
// Notice, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// else a pointer to the underlying data.
|
||||
//
|
||||
// 返回原始数据数组.
|
||||
func (a *SortedIntArray) Slice() []int {
|
||||
array := ([]int)(nil)
|
||||
if a.mu.IsSafe() {
|
||||
@ -311,24 +278,19 @@ func (a *SortedIntArray) Slice() []int {
|
||||
return array
|
||||
}
|
||||
|
||||
// Check whether a value exists in the array.
|
||||
//
|
||||
// 查找指定数值是否存在。
|
||||
// Contains checks whether a value exists in the array.
|
||||
func (a *SortedIntArray) Contains(value int) bool {
|
||||
return a.Search(value) == 0
|
||||
}
|
||||
|
||||
// Search array by <value>, returns the index of <value>, returns -1 if not exists.
|
||||
//
|
||||
// 查找指定数值的索引位置,返回索引位置,如果查找不到则返回-1。
|
||||
// Search searches array by <value>, returns the index of <value>,
|
||||
// or returns -1 if not exists.
|
||||
func (a *SortedIntArray) Search(value int) (index int) {
|
||||
index, _ = a.binSearch(value, true)
|
||||
return
|
||||
}
|
||||
|
||||
// Binary search.
|
||||
//
|
||||
// 二分查找.
|
||||
func (a *SortedIntArray) binSearch(value int, lock bool) (index int, result int) {
|
||||
if len(a.array) == 0 {
|
||||
return -1, -2
|
||||
@ -354,11 +316,9 @@ func (a *SortedIntArray) binSearch(value int, lock bool) (index int, result int)
|
||||
return mid, cmp
|
||||
}
|
||||
|
||||
// Set unique mark to the array,
|
||||
// SetUnique sets unique mark to the array,
|
||||
// which means it does not contain any repeated items.
|
||||
// It also do unique check, remove all repeated items.
|
||||
//
|
||||
// 设置是否允许数组唯一.
|
||||
func (a *SortedIntArray) SetUnique(unique bool) *SortedIntArray {
|
||||
oldUnique := a.unique.Val()
|
||||
a.unique.Set(unique)
|
||||
@ -368,9 +328,7 @@ func (a *SortedIntArray) SetUnique(unique bool) *SortedIntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Do unique check, remove all repeated items.
|
||||
//
|
||||
// 清理数组中重复的元素项.
|
||||
// Unique uniques the array, clear repeated items.
|
||||
func (a *SortedIntArray) Unique() *SortedIntArray {
|
||||
a.mu.Lock()
|
||||
i := 0
|
||||
@ -388,9 +346,7 @@ func (a *SortedIntArray) Unique() *SortedIntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Return a new array, which is a copy of current array.
|
||||
//
|
||||
// 克隆当前数组,返回当前数组的一个拷贝。
|
||||
// Clone returns a new array, which is a copy of current array.
|
||||
func (a *SortedIntArray) Clone() (newArray *SortedIntArray) {
|
||||
a.mu.RLock()
|
||||
array := make([]int, len(a.array))
|
||||
@ -399,9 +355,7 @@ func (a *SortedIntArray) Clone() (newArray *SortedIntArray) {
|
||||
return NewSortedIntArrayFrom(array, !a.mu.IsSafe())
|
||||
}
|
||||
|
||||
// Clear array.
|
||||
//
|
||||
// 清空数据数组。
|
||||
// Clear deletes all items of current array.
|
||||
func (a *SortedIntArray) Clear() *SortedIntArray {
|
||||
a.mu.Lock()
|
||||
if len(a.array) > 0 {
|
||||
@ -411,9 +365,7 @@ func (a *SortedIntArray) Clear() *SortedIntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Lock writing by callback function f.
|
||||
//
|
||||
// 使用自定义方法执行加锁修改操作。
|
||||
// LockFunc locks writing by callback function <f>.
|
||||
func (a *SortedIntArray) LockFunc(f func(array []int)) *SortedIntArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -421,9 +373,7 @@ func (a *SortedIntArray) LockFunc(f func(array []int)) *SortedIntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Lock reading by callback function f.
|
||||
//
|
||||
// 使用自定义方法执行加锁读取操作。
|
||||
// RLockFunc locks reading by callback function <f>.
|
||||
func (a *SortedIntArray) RLockFunc(f func(array []int)) *SortedIntArray {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -431,11 +381,10 @@ func (a *SortedIntArray) RLockFunc(f func(array []int)) *SortedIntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Merge two arrays. The parameter <array> can be any garray type or slice type.
|
||||
// The difference between Merge and Add is Add supports only specified slice type,
|
||||
// but Merge supports more variable types.
|
||||
//
|
||||
// 合并两个数组, 支持任意的garray数组类型及slice类型.
|
||||
// Merge merges <array> into current array.
|
||||
// The parameter <array> can be any garray or slice type.
|
||||
// The difference between Merge and Append is Append supports only specified slice type,
|
||||
// but Merge supports more parameter types.
|
||||
func (a *SortedIntArray) Merge(array interface{}) *SortedIntArray {
|
||||
switch v := array.(type) {
|
||||
case *Array: a.Add(gconv.Ints(v.Slice())...)
|
||||
@ -450,10 +399,9 @@ func (a *SortedIntArray) Merge(array interface{}) *SortedIntArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Chunks an array into arrays with size elements.
|
||||
// Chunk splits an array into multiple arrays,
|
||||
// the size of each array is determined by <size>.
|
||||
// The last chunk may contain less than size elements.
|
||||
//
|
||||
// 将一个数组分割成多个数组,其中每个数组的单元数目由size决定。最后一个数组的单元数目可能会少于size个。
|
||||
func (a *SortedIntArray) Chunk(size int) [][]int {
|
||||
if size < 1 {
|
||||
return nil
|
||||
@ -474,12 +422,9 @@ func (a *SortedIntArray) Chunk(size int) [][]int {
|
||||
return n
|
||||
}
|
||||
|
||||
// Extract a slice of the array(If in concurrent safe usage,
|
||||
// it returns a copy of the slice; else a pointer).
|
||||
// It returns the sequence of elements from the array array as specified
|
||||
// by the offset and length parameters.
|
||||
//
|
||||
// 返回根据offset和size参数所指定的数组中的一段序列。
|
||||
// SubSlice returns a slice of elements from the array as specified
|
||||
// by the <offset> and <size> parameters.
|
||||
// If in concurrent safe usage, it returns a copy of the slice; else a pointer.
|
||||
func (a *SortedIntArray) SubSlice(offset, size int) []int {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -498,18 +443,14 @@ func (a *SortedIntArray) SubSlice(offset, size int) []int {
|
||||
}
|
||||
}
|
||||
|
||||
// Rand gets one random entry from array.
|
||||
//
|
||||
// 从数组中随机获得1个元素项(不删除)。
|
||||
// Rand randomly returns one item from array(no deleting).
|
||||
func (a *SortedIntArray) Rand() int {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return a.array[grand.Intn(len(a.array))]
|
||||
}
|
||||
|
||||
// Rands gets one or more random entries from array(a copy).
|
||||
//
|
||||
// 从数组中随机拷贝size个元素项,构成slice返回。
|
||||
// Rands randomly returns <size> items from array(no deleting).
|
||||
func (a *SortedIntArray) Rands(size int) []int {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -526,9 +467,7 @@ func (a *SortedIntArray) Rands(size int) []int {
|
||||
return n
|
||||
}
|
||||
|
||||
// Join array elements with a string.
|
||||
//
|
||||
// 使用glue字符串串连当前数组的元素项,构造成新的字符串返回。
|
||||
// Join joins array elements with a string <glue>.
|
||||
func (a *SortedIntArray) Join(glue string) string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -540,4 +479,22 @@ func (a *SortedIntArray) Join(glue string) string {
|
||||
}
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// CountValues counts the number of occurrences of all values in the array.
|
||||
func (a *SortedIntArray) CountValues() map[int]int {
|
||||
m := make(map[int]int)
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
for _, v := range a.array {
|
||||
m[v]++
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// String returns current array as a string.
|
||||
func (a *SortedIntArray) String() string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return fmt.Sprint(a.array)
|
||||
}
|
||||
@ -8,7 +8,8 @@ package garray
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/gogf/gf/g/container/gtype"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/g/container/gtype"
|
||||
"github.com/gogf/gf/g/internal/rwmutex"
|
||||
"github.com/gogf/gf/g/util/gconv"
|
||||
"github.com/gogf/gf/g/util/grand"
|
||||
@ -16,36 +17,27 @@ import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// 默认按照从小到大进行排序
|
||||
// It's using increasing order in default.
|
||||
type SortedArray struct {
|
||||
mu *rwmutex.RWMutex // 互斥锁
|
||||
array []interface{} // 底层数组
|
||||
unique *gtype.Bool // 是否要求不能重复
|
||||
compareFunc func(v1, v2 interface{}) int // 比较函数,返回值 -1: v1 < v2;0: v1 == v2;1: v1 > v2
|
||||
mu *rwmutex.RWMutex
|
||||
array []interface{}
|
||||
unique *gtype.Bool // Whether enable unique feature(false)
|
||||
compareFunc func(v1, v2 interface{}) int // Comparison function(it returns -1: v1 < v2; 0: v1 == v2; 1: v1 > v2)
|
||||
}
|
||||
|
||||
// Create an empty sorted array.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
// NewSortedArray creates and returns an empty sorted array.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety, which is false in default.
|
||||
// The param <compareFunc> used to compare values to sort in array,
|
||||
// if it returns value < 0, means v1 < v2;
|
||||
// if it returns value = 0, means v1 = v2;
|
||||
// if it returns value > 0, means v1 > v2;
|
||||
//
|
||||
// 创建一个空的排序数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// 参数compareFunc用于指定排序方法:
|
||||
// 如果返回值 < 0, 表示 v1 < v2;
|
||||
// 如果返回值 = 0, 表示 v1 = v2;
|
||||
// 如果返回值 > 0, 表示 v1 > v2;
|
||||
func NewSortedArray(compareFunc func(v1, v2 interface{}) int, unsafe...bool) *SortedArray {
|
||||
return NewSortedArraySize(0, compareFunc, unsafe...)
|
||||
}
|
||||
|
||||
// Create a sorted array with given size and cap.
|
||||
// NewSortedArraySize create and returns an sorted array with given size and cap.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 创建一个指定大小的排序数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewSortedArraySize(cap int, compareFunc func(v1, v2 interface{}) int, unsafe...bool) *SortedArray {
|
||||
return &SortedArray{
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -55,11 +47,9 @@ func NewSortedArraySize(cap int, compareFunc func(v1, v2 interface{}) int, unsaf
|
||||
}
|
||||
}
|
||||
|
||||
// Create an array with given slice <array>.
|
||||
// NewSortedArrayFrom creates and returns an sorted array with given slice <array>.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 通过给定的slice变量创建排序数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewSortedArrayFrom(array []interface{}, compareFunc func(v1, v2 interface{}) int, unsafe...bool) *SortedArray {
|
||||
a := NewSortedArraySize(0, compareFunc, unsafe...)
|
||||
a.array = array
|
||||
@ -69,11 +59,9 @@ func NewSortedArrayFrom(array []interface{}, compareFunc func(v1, v2 interface{}
|
||||
return a
|
||||
}
|
||||
|
||||
// Create an array from a copy of given slice <array>.
|
||||
// NewSortedArrayFromCopy creates and returns an sorted array from a copy of given slice <array>.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 通过给定的slice拷贝创建数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewSortedArrayFromCopy(array []interface{}, unsafe...bool) *SortedArray {
|
||||
newArray := make([]interface{}, len(array))
|
||||
copy(newArray, array)
|
||||
@ -83,9 +71,7 @@ func NewSortedArrayFromCopy(array []interface{}, unsafe...bool) *SortedArray {
|
||||
}
|
||||
}
|
||||
|
||||
// Set the underlying slice array with the given <array> param.
|
||||
//
|
||||
// 设置底层数组变量.
|
||||
// SetArray sets the underlying slice array with the given <array>.
|
||||
func (a *SortedArray) SetArray(array []interface{}) *SortedArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -96,9 +82,9 @@ func (a *SortedArray) SetArray(array []interface{}) *SortedArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Sort the array by comparing function.
|
||||
//
|
||||
// 将数组按照比较方法进行排序.
|
||||
// Sort sorts the array in increasing order.
|
||||
// The param <reverse> controls whether sort
|
||||
// in increasing order(default) or decreasing order
|
||||
func (a *SortedArray) Sort() *SortedArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -108,9 +94,7 @@ func (a *SortedArray) Sort() *SortedArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// And values to sorted array, the array always keeps sorted.
|
||||
//
|
||||
// 添加数据项.
|
||||
// Add adds one or multiple values to sorted array, the array always keeps sorted.
|
||||
func (a *SortedArray) Add(values...interface{}) *SortedArray {
|
||||
if len(values) == 0 {
|
||||
return a
|
||||
@ -126,7 +110,6 @@ func (a *SortedArray) Add(values...interface{}) *SortedArray {
|
||||
a.array = append(a.array, value)
|
||||
continue
|
||||
}
|
||||
// 加到指定索引后面
|
||||
if cmp > 0 {
|
||||
index++
|
||||
}
|
||||
@ -137,9 +120,8 @@ func (a *SortedArray) Add(values...interface{}) *SortedArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Get value by index.
|
||||
//
|
||||
// 获取指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Get returns the value of the specified index,
|
||||
// the caller should notice the boundary of the array.
|
||||
func (a *SortedArray) Get(index int) interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -147,13 +129,11 @@ func (a *SortedArray) Get(index int) interface{} {
|
||||
return value
|
||||
}
|
||||
|
||||
// Remove an item by index.
|
||||
//
|
||||
// 删除指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Remove removes an item by index.
|
||||
func (a *SortedArray) Remove(index int) interface{} {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
// 边界删除判断,以提高删除效率
|
||||
// Determine array boundaries when deleting to improve deletion efficiency.
|
||||
if index == 0 {
|
||||
value := a.array[0]
|
||||
a.array = a.array[1 : ]
|
||||
@ -163,15 +143,15 @@ func (a *SortedArray) Remove(index int) interface{} {
|
||||
a.array = a.array[: index]
|
||||
return value
|
||||
}
|
||||
// 如果非边界删除,会涉及到数组创建,那么删除的效率差一些
|
||||
// If it is a non-boundary delete,
|
||||
// it will involve the creation of an array,
|
||||
// then the deletion is less efficient.
|
||||
value := a.array[index]
|
||||
a.array = append(a.array[ : index], a.array[index + 1 : ]...)
|
||||
return value
|
||||
}
|
||||
|
||||
// Push new items to the beginning of array.
|
||||
//
|
||||
// 将数据项添加到数组的最左端(索引为0)。
|
||||
// PopLeft pops and returns an item from the beginning of array.
|
||||
func (a *SortedArray) PopLeft() interface{} {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -180,9 +160,7 @@ func (a *SortedArray) PopLeft() interface{} {
|
||||
return value
|
||||
}
|
||||
|
||||
// Push new items to the end of array.
|
||||
//
|
||||
// 将数据项添加到数组的最右端(索引为length - 1)。
|
||||
// PopRight pops and returns an item from the end of array.
|
||||
func (a *SortedArray) PopRight() interface{} {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -192,16 +170,12 @@ func (a *SortedArray) PopRight() interface{} {
|
||||
return value
|
||||
}
|
||||
|
||||
// PopRand picks an random item out of array.
|
||||
//
|
||||
// 随机将一个数据项移出数组,并返回该数据项。
|
||||
// PopRand randomly pops and return an item out of array.
|
||||
func (a *SortedArray) PopRand() interface{} {
|
||||
return a.Remove(grand.Intn(len(a.array)))
|
||||
}
|
||||
|
||||
// PopRands picks <size> items out of array.
|
||||
//
|
||||
// 随机将size个数据项移出数组,并返回该数据项。
|
||||
// PopRands randomly pops and returns <size> items out of array.
|
||||
func (a *SortedArray) PopRands(size int) []interface{} {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -217,9 +191,7 @@ func (a *SortedArray) PopRands(size int) []interface{} {
|
||||
return array
|
||||
}
|
||||
|
||||
// Pop <size> items from the beginning of array.
|
||||
//
|
||||
// 将最左端(首部)的size个数据项移出数组,并返回该数据项
|
||||
// PopLefts pops and returns <size> items from the beginning of array.
|
||||
func (a *SortedArray) PopLefts(size int) []interface{} {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -232,9 +204,7 @@ func (a *SortedArray) PopLefts(size int) []interface{} {
|
||||
return value
|
||||
}
|
||||
|
||||
// Pop <size> items from the end of array.
|
||||
//
|
||||
// 将最右端(尾部)的size个数据项移出数组,并返回该数据项
|
||||
// PopRights pops and returns <size> items from the end of array.
|
||||
func (a *SortedArray) PopRights(size int) []interface{} {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -247,11 +217,9 @@ func (a *SortedArray) PopRights(size int) []interface{} {
|
||||
return value
|
||||
}
|
||||
|
||||
// Get items by range, returns array[start:end].
|
||||
// Be aware that, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// Range picks and returns items by range, like array[start:end].
|
||||
// Notice, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// else a pointer to the underlying data.
|
||||
//
|
||||
// 将最右端(尾部)的size个数据项移出数组,并返回该数据项
|
||||
func (a *SortedArray) Range(start, end int) []interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -277,9 +245,7 @@ func (a *SortedArray) Range(start, end int) []interface{} {
|
||||
return array
|
||||
}
|
||||
|
||||
// Calculate the sum of values in an array.
|
||||
//
|
||||
// 对数组中的元素项求和(将元素值转换为int类型后叠加)。
|
||||
// Sum returns the sum of values in an array.
|
||||
func (a *SortedArray) Sum() (sum int) {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -289,9 +255,7 @@ func (a *SortedArray) Sum() (sum int) {
|
||||
return
|
||||
}
|
||||
|
||||
// Get the length of array.
|
||||
//
|
||||
// 数组长度。
|
||||
// Len returns the length of array.
|
||||
func (a *SortedArray) Len() int {
|
||||
a.mu.RLock()
|
||||
length := len(a.array)
|
||||
@ -299,11 +263,9 @@ func (a *SortedArray) Len() int {
|
||||
return length
|
||||
}
|
||||
|
||||
// Get the underlying data of array.
|
||||
// Be aware that, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// Slice returns the underlying data of array.
|
||||
// Notice, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// else a pointer to the underlying data.
|
||||
//
|
||||
// 返回原始数据数组.
|
||||
func (a *SortedArray) Slice() []interface{} {
|
||||
array := ([]interface{})(nil)
|
||||
if a.mu.IsSafe() {
|
||||
@ -317,25 +279,19 @@ func (a *SortedArray) Slice() []interface{} {
|
||||
return array
|
||||
}
|
||||
|
||||
// Check whether a value exists in the array.
|
||||
//
|
||||
// 查找指定数值是否存在。
|
||||
// Contains checks whether a value exists in the array.
|
||||
func (a *SortedArray) Contains(value interface{}) bool {
|
||||
return a.Search(value) == 0
|
||||
}
|
||||
|
||||
// Search array by <value>, returns the index of <value>, returns -1 if not exists.
|
||||
//
|
||||
// 查找指定数值的索引位置,返回索引位置,如果查找不到则返回-1。
|
||||
// Search searches array by <value>, returns the index of <value>,
|
||||
// or returns -1 if not exists.
|
||||
func (a *SortedArray) Search(value interface{}) (index int) {
|
||||
index, _ = a.binSearch(value, true)
|
||||
return
|
||||
}
|
||||
|
||||
// Binary search.
|
||||
//
|
||||
// 二分查找。查找指定数值的索引位置,返回索引位置(具体匹配位置或者最后对比位置)及查找结果
|
||||
// 返回值: 最后比较位置, 比较结果。
|
||||
func (a *SortedArray) binSearch(value interface{}, lock bool)(index int, result int) {
|
||||
if len(a.array) == 0 {
|
||||
return -1, -2
|
||||
@ -361,11 +317,9 @@ func (a *SortedArray) binSearch(value interface{}, lock bool)(index int, result
|
||||
return mid, cmp
|
||||
}
|
||||
|
||||
// Set unique mark to the array,
|
||||
// SetUnique sets unique mark to the array,
|
||||
// which means it does not contain any repeated items.
|
||||
// It also do unique check, remove all repeated items.
|
||||
//
|
||||
// 设置是否允许数组唯一.
|
||||
func (a *SortedArray) SetUnique(unique bool) *SortedArray {
|
||||
oldUnique := a.unique.Val()
|
||||
a.unique.Set(unique)
|
||||
@ -375,9 +329,7 @@ func (a *SortedArray) SetUnique(unique bool) *SortedArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Do unique check, remove all repeated items.
|
||||
//
|
||||
// 清理数组中重复的元素项.
|
||||
// Unique uniques the array, clear repeated items.
|
||||
func (a *SortedArray) Unique() *SortedArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -395,9 +347,7 @@ func (a *SortedArray) Unique() *SortedArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Return a new array, which is a copy of current array.
|
||||
//
|
||||
// 克隆当前数组,返回当前数组的一个拷贝。
|
||||
// Clone returns a new array, which is a copy of current array.
|
||||
func (a *SortedArray) Clone() (newArray *SortedArray) {
|
||||
a.mu.RLock()
|
||||
array := make([]interface{}, len(a.array))
|
||||
@ -406,9 +356,7 @@ func (a *SortedArray) Clone() (newArray *SortedArray) {
|
||||
return NewSortedArrayFrom(array, a.compareFunc, !a.mu.IsSafe())
|
||||
}
|
||||
|
||||
// Clear array.
|
||||
//
|
||||
// 清空数据数组。
|
||||
// Clear deletes all items of current array.
|
||||
func (a *SortedArray) Clear() *SortedArray {
|
||||
a.mu.Lock()
|
||||
if len(a.array) > 0 {
|
||||
@ -418,9 +366,7 @@ func (a *SortedArray) Clear() *SortedArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Lock writing by callback function f.
|
||||
//
|
||||
// 使用自定义方法执行加锁修改操作。
|
||||
// LockFunc locks writing by callback function <f>.
|
||||
func (a *SortedArray) LockFunc(f func(array []interface{})) *SortedArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -428,9 +374,7 @@ func (a *SortedArray) LockFunc(f func(array []interface{})) *SortedArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Lock reading by callback function f.
|
||||
//
|
||||
// 使用自定义方法执行加锁读取操作。
|
||||
// RLockFunc locks reading by callback function <f>.
|
||||
func (a *SortedArray) RLockFunc(f func(array []interface{})) *SortedArray {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -438,11 +382,10 @@ func (a *SortedArray) RLockFunc(f func(array []interface{})) *SortedArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Merge two arrays. The parameter <array> can be any garray type or slice type.
|
||||
// The difference between Merge and Add is Add supports only specified slice type,
|
||||
// but Merge supports more variable types.
|
||||
//
|
||||
// 合并两个数组, 支持任意的garray数组类型及slice类型.
|
||||
// Merge merges <array> into current array.
|
||||
// The parameter <array> can be any garray or slice type.
|
||||
// The difference between Merge and Append is Append supports only specified slice type,
|
||||
// but Merge supports more parameter types.
|
||||
func (a *SortedArray) Merge(array interface{}) *SortedArray {
|
||||
switch v := array.(type) {
|
||||
case *Array: a.Add(gconv.Interfaces(v.Slice())...)
|
||||
@ -457,10 +400,9 @@ func (a *SortedArray) Merge(array interface{}) *SortedArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Chunks an array into arrays with size elements.
|
||||
// Chunk splits an array into multiple arrays,
|
||||
// the size of each array is determined by <size>.
|
||||
// The last chunk may contain less than size elements.
|
||||
//
|
||||
// 将一个数组分割成多个数组,其中每个数组的单元数目由size决定。最后一个数组的单元数目可能会少于size个。
|
||||
func (a *SortedArray) Chunk(size int) [][]interface{} {
|
||||
if size < 1 {
|
||||
return nil
|
||||
@ -481,12 +423,9 @@ func (a *SortedArray) Chunk(size int) [][]interface{} {
|
||||
return n
|
||||
}
|
||||
|
||||
// Extract a slice of the array(If in concurrent safe usage,
|
||||
// it returns a copy of the slice; else a pointer).
|
||||
// It returns the sequence of elements from the array array as specified
|
||||
// by the offset and length parameters.
|
||||
//
|
||||
// 返回根据offset和size参数所指定的数组中的一段序列。
|
||||
// SubSlice returns a slice of elements from the array as specified
|
||||
// by the <offset> and <size> parameters.
|
||||
// If in concurrent safe usage, it returns a copy of the slice; else a pointer.
|
||||
func (a *SortedArray) SubSlice(offset, size int) []interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -505,18 +444,14 @@ func (a *SortedArray) SubSlice(offset, size int) []interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
// Rand gets one random entry from array.
|
||||
//
|
||||
// 从数组中随机获得1个元素项(不删除)。
|
||||
// Rand randomly returns one item from array(no deleting).
|
||||
func (a *SortedArray) Rand() interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return a.array[grand.Intn(len(a.array))]
|
||||
}
|
||||
|
||||
// Rands gets one or more random entries from array(a copy).
|
||||
//
|
||||
// 从数组中随机拷贝size个元素项,构成slice返回。
|
||||
// Rands randomly returns <size> items from array(no deleting).
|
||||
func (a *SortedArray) Rands(size int) []interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -533,9 +468,7 @@ func (a *SortedArray) Rands(size int) []interface{} {
|
||||
return n
|
||||
}
|
||||
|
||||
// Join array elements with a string.
|
||||
//
|
||||
// 使用glue字符串串连当前数组的元素项,构造成新的字符串返回。
|
||||
// Join joins array elements with a string <glue>.
|
||||
func (a *SortedArray) Join(glue string) string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -547,4 +480,22 @@ func (a *SortedArray) Join(glue string) string {
|
||||
}
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// CountValues counts the number of occurrences of all values in the array.
|
||||
func (a *SortedArray) CountValues() map[interface{}]int {
|
||||
m := make(map[interface{}]int)
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
for _, v := range a.array {
|
||||
m[v]++
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// String returns current array as a string.
|
||||
func (a *SortedArray) String() string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return fmt.Sprint(a.array)
|
||||
}
|
||||
@ -8,7 +8,8 @@ package garray
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/gogf/gf/g/container/gtype"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/g/container/gtype"
|
||||
"github.com/gogf/gf/g/internal/rwmutex"
|
||||
"github.com/gogf/gf/g/util/gconv"
|
||||
"github.com/gogf/gf/g/util/grand"
|
||||
@ -17,28 +18,24 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 默认按照从小到大进行排序
|
||||
// It's using increasing order in default.
|
||||
type SortedStringArray struct {
|
||||
mu *rwmutex.RWMutex // 互斥锁
|
||||
array []string // 底层数组
|
||||
unique *gtype.Bool // 是否要求不能重复
|
||||
compareFunc func(v1, v2 string) int // 比较函数,返回值 -1: v1 < v2;0: v1 == v2;1: v1 > v2
|
||||
mu *rwmutex.RWMutex
|
||||
array []string
|
||||
unique *gtype.Bool // Whether enable unique feature(false)
|
||||
compareFunc func(v1, v2 string) int // Comparison function(it returns -1: v1 < v2; 0: v1 == v2; 1: v1 > v2)
|
||||
}
|
||||
|
||||
// Create an empty sorted array.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 创建一个空的排序数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// NewSortedStringArray creates and returns an empty sorted array.
|
||||
// The param <unsafe> used to specify whether using array in un-concurrent-safety,
|
||||
// which is false in default.
|
||||
func NewSortedStringArray(unsafe...bool) *SortedStringArray {
|
||||
return NewSortedStringArraySize(0, unsafe...)
|
||||
}
|
||||
|
||||
// Create a sorted array with given size and cap.
|
||||
// NewSortedStringArraySize create and returns an sorted array with given size and cap.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 创建一个指定大小的排序数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewSortedStringArraySize(cap int, unsafe...bool) *SortedStringArray {
|
||||
return &SortedStringArray {
|
||||
mu : rwmutex.New(unsafe...),
|
||||
@ -50,11 +47,9 @@ func NewSortedStringArraySize(cap int, unsafe...bool) *SortedStringArray {
|
||||
}
|
||||
}
|
||||
|
||||
// Create an array with given slice <array>.
|
||||
// NewSortedStringArrayFrom creates and returns an sorted array with given slice <array>.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 通过给定的slice变量创建排序数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewSortedStringArrayFrom(array []string, unsafe...bool) *SortedStringArray {
|
||||
a := NewSortedStringArraySize(0, unsafe...)
|
||||
a.array = array
|
||||
@ -62,11 +57,9 @@ func NewSortedStringArrayFrom(array []string, unsafe...bool) *SortedStringArray
|
||||
return a
|
||||
}
|
||||
|
||||
// Create an array from a copy of given slice <array>.
|
||||
// NewSortedStringArrayFromCopy creates and returns an sorted array from a copy of given slice <array>.
|
||||
// The param <unsafe> used to specify whether using array with un-concurrent-safety,
|
||||
// which is false in default, means concurrent-safe in default.
|
||||
//
|
||||
// 通过给定的slice拷贝创建数组对象,参数unsafe用于指定是否用于非并发安全场景,默认为false,表示并发安全。
|
||||
// which is false in default.
|
||||
func NewSortedStringArrayFromCopy(array []string, unsafe...bool) *SortedStringArray {
|
||||
newArray := make([]string, len(array))
|
||||
copy(newArray, array)
|
||||
@ -76,9 +69,7 @@ func NewSortedStringArrayFromCopy(array []string, unsafe...bool) *SortedStringAr
|
||||
}
|
||||
}
|
||||
|
||||
// Set the underlying slice array with the given <array> param.
|
||||
//
|
||||
// 设置底层数组变量.
|
||||
// SetArray sets the underlying slice array with the given <array>.
|
||||
func (a *SortedStringArray) SetArray(array []string) *SortedStringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -87,9 +78,9 @@ func (a *SortedStringArray) SetArray(array []string) *SortedStringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Sort the array in increasing order.
|
||||
//
|
||||
// 将数组排序(默认从低到高).
|
||||
// Sort sorts the array in increasing order.
|
||||
// The param <reverse> controls whether sort
|
||||
// in increasing order(default) or decreasing order.
|
||||
func (a *SortedStringArray) Sort() *SortedStringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -97,9 +88,7 @@ func (a *SortedStringArray) Sort() *SortedStringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// And values to sorted array, the array always keeps sorted.
|
||||
//
|
||||
// 添加数据项.
|
||||
// Add adds one or multiple values to sorted array, the array always keeps sorted.
|
||||
func (a *SortedStringArray) Add(values...string) *SortedStringArray {
|
||||
if len(values) == 0 {
|
||||
return a
|
||||
@ -115,7 +104,6 @@ func (a *SortedStringArray) Add(values...string) *SortedStringArray {
|
||||
a.array = append(a.array, value)
|
||||
continue
|
||||
}
|
||||
// 加到指定索引后面
|
||||
if cmp > 0 {
|
||||
index++
|
||||
}
|
||||
@ -126,9 +114,8 @@ func (a *SortedStringArray) Add(values...string) *SortedStringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Get value by index.
|
||||
//
|
||||
// 获取指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Get returns the value of the specified index,
|
||||
// the caller should notice the boundary of the array.
|
||||
func (a *SortedStringArray) Get(index int) string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -136,13 +123,11 @@ func (a *SortedStringArray) Get(index int) string {
|
||||
return value
|
||||
}
|
||||
|
||||
// Remove an item by index.
|
||||
//
|
||||
// 删除指定索引的数据项, 调用方注意判断数组边界。
|
||||
// Remove removes an item by index.
|
||||
func (a *SortedStringArray) Remove(index int) string {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
// 边界删除判断,以提高删除效率
|
||||
// Determine array boundaries when deleting to improve deletion efficiency.
|
||||
if index == 0 {
|
||||
value := a.array[0]
|
||||
a.array = a.array[1 : ]
|
||||
@ -152,15 +137,15 @@ func (a *SortedStringArray) Remove(index int) string {
|
||||
a.array = a.array[: index]
|
||||
return value
|
||||
}
|
||||
// 如果非边界删除,会涉及到数组创建,那么删除的效率差一些
|
||||
// If it is a non-boundary delete,
|
||||
// it will involve the creation of an array,
|
||||
// then the deletion is less efficient.
|
||||
value := a.array[index]
|
||||
a.array = append(a.array[ : index], a.array[index + 1 : ]...)
|
||||
return value
|
||||
}
|
||||
|
||||
// Push new items to the beginning of array.
|
||||
//
|
||||
// 将数据项添加到数组的最左端(索引为0)。
|
||||
// PopLeft pops and returns an item from the beginning of array.
|
||||
func (a *SortedStringArray) PopLeft() string {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -169,9 +154,7 @@ func (a *SortedStringArray) PopLeft() string {
|
||||
return value
|
||||
}
|
||||
|
||||
// Push new items to the end of array.
|
||||
//
|
||||
// 将数据项添加到数组的最右端(索引为length - 1)。
|
||||
// PopRight pops and returns an item from the end of array.
|
||||
func (a *SortedStringArray) PopRight() string {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -181,16 +164,12 @@ func (a *SortedStringArray) PopRight() string {
|
||||
return value
|
||||
}
|
||||
|
||||
// PopRand picks an random item out of array.
|
||||
//
|
||||
// 随机将一个数据项移出数组,并返回该数据项。
|
||||
// PopRand randomly pops and return an item out of array.
|
||||
func (a *SortedStringArray) PopRand() string {
|
||||
return a.Remove(grand.Intn(len(a.array)))
|
||||
}
|
||||
|
||||
// PopRands picks <size> items out of array.
|
||||
//
|
||||
// 随机将size个数据项移出数组,并返回该数据项。
|
||||
// PopRands randomly pops and returns <size> items out of array.
|
||||
func (a *SortedStringArray) PopRands(size int) []string {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -206,9 +185,7 @@ func (a *SortedStringArray) PopRands(size int) []string {
|
||||
return array
|
||||
}
|
||||
|
||||
// Pop <size> items from the beginning of array.
|
||||
//
|
||||
// 将最左端(首部)的size个数据项移出数组,并返回该数据项
|
||||
// PopLefts pops and returns <size> items from the beginning of array.
|
||||
func (a *SortedStringArray) PopLefts(size int) []string {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -221,9 +198,7 @@ func (a *SortedStringArray) PopLefts(size int) []string {
|
||||
return value
|
||||
}
|
||||
|
||||
// Pop <size> items from the end of array.
|
||||
//
|
||||
// 将最右端(尾部)的size个数据项移出数组,并返回该数据项
|
||||
// PopRights pops and returns <size> items from the end of array.
|
||||
func (a *SortedStringArray) PopRights(size int) []string {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -236,11 +211,9 @@ func (a *SortedStringArray) PopRights(size int) []string {
|
||||
return value
|
||||
}
|
||||
|
||||
// Get items by range, returns array[start:end].
|
||||
// Be aware that, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// Range picks and returns items by range, like array[start:end].
|
||||
// Notice, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// else a pointer to the underlying data.
|
||||
//
|
||||
// 将最右端(尾部)的size个数据项移出数组,并返回该数据项
|
||||
func (a *SortedStringArray) Range(start, end int) []string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -266,9 +239,7 @@ func (a *SortedStringArray) Range(start, end int) []string {
|
||||
return array
|
||||
}
|
||||
|
||||
// Calculate the sum of values in an array.
|
||||
//
|
||||
// 对数组中的元素项求和(将元素值转换为int类型后叠加)。
|
||||
// Sum returns the sum of values in an array.
|
||||
func (a *SortedStringArray) Sum() (sum int) {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -278,9 +249,7 @@ func (a *SortedStringArray) Sum() (sum int) {
|
||||
return
|
||||
}
|
||||
|
||||
// Get the length of array.
|
||||
//
|
||||
// 数组长度。
|
||||
// Len returns the length of array.
|
||||
func (a *SortedStringArray) Len() int {
|
||||
a.mu.RLock()
|
||||
length := len(a.array)
|
||||
@ -288,11 +257,9 @@ func (a *SortedStringArray) Len() int {
|
||||
return length
|
||||
}
|
||||
|
||||
// Get the underlying data of array.
|
||||
// Be aware that, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// Slice returns the underlying data of array.
|
||||
// Notice, if in concurrent-safe usage, it returns a copy of slice;
|
||||
// else a pointer to the underlying data.
|
||||
//
|
||||
// 返回原始数据数组.
|
||||
func (a *SortedStringArray) Slice() []string {
|
||||
array := ([]string)(nil)
|
||||
if a.mu.IsSafe() {
|
||||
@ -306,24 +273,19 @@ func (a *SortedStringArray) Slice() []string {
|
||||
return array
|
||||
}
|
||||
|
||||
// Check whether a value exists in the array.
|
||||
//
|
||||
// 查找指定数值是否存在。
|
||||
// Contains checks whether a value exists in the array.
|
||||
func (a *SortedStringArray) Contains(value string) bool {
|
||||
return a.Search(value) == 0
|
||||
}
|
||||
|
||||
// Search array by <value>, returns the index of <value>, returns -1 if not exists.
|
||||
//
|
||||
// 查找指定数值的索引位置,返回索引位置,如果查找不到则返回-1。
|
||||
// Search searches array by <value>, returns the index of <value>,
|
||||
// or returns -1 if not exists.
|
||||
func (a *SortedStringArray) Search(value string) (index int) {
|
||||
index, _ = a.binSearch(value, true)
|
||||
return
|
||||
}
|
||||
|
||||
// Binary search.
|
||||
//
|
||||
// 二分查找.
|
||||
func (a *SortedStringArray) binSearch(value string, lock bool) (index int, result int) {
|
||||
if len(a.array) == 0 {
|
||||
return -1, -2
|
||||
@ -349,11 +311,9 @@ func (a *SortedStringArray) binSearch(value string, lock bool) (index int, resul
|
||||
return mid, cmp
|
||||
}
|
||||
|
||||
// Set unique mark to the array,
|
||||
// SetUnique sets unique mark to the array,
|
||||
// which means it does not contain any repeated items.
|
||||
// It also do unique check, remove all repeated items.
|
||||
//
|
||||
// 设置是否允许数组唯一.
|
||||
func (a *SortedStringArray) SetUnique(unique bool) *SortedStringArray {
|
||||
oldUnique := a.unique.Val()
|
||||
a.unique.Set(unique)
|
||||
@ -363,9 +323,7 @@ func (a *SortedStringArray) SetUnique(unique bool) *SortedStringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Do unique check, remove all repeated items.
|
||||
//
|
||||
// 清理数组中重复的元素项.
|
||||
// Unique uniques the array, clear repeated items.
|
||||
func (a *SortedStringArray) Unique() *SortedStringArray {
|
||||
a.mu.Lock()
|
||||
i := 0
|
||||
@ -383,9 +341,7 @@ func (a *SortedStringArray) Unique() *SortedStringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Return a new array, which is a copy of current array.
|
||||
//
|
||||
// 克隆当前数组,返回当前数组的一个拷贝。
|
||||
// Clone returns a new array, which is a copy of current array.
|
||||
func (a *SortedStringArray) Clone() (newArray *SortedStringArray) {
|
||||
a.mu.RLock()
|
||||
array := make([]string, len(a.array))
|
||||
@ -394,9 +350,7 @@ func (a *SortedStringArray) Clone() (newArray *SortedStringArray) {
|
||||
return NewSortedStringArrayFrom(array, !a.mu.IsSafe())
|
||||
}
|
||||
|
||||
// Clear array.
|
||||
//
|
||||
// 清空数据数组。
|
||||
// Clear deletes all items of current array.
|
||||
func (a *SortedStringArray) Clear() *SortedStringArray {
|
||||
a.mu.Lock()
|
||||
if len(a.array) > 0 {
|
||||
@ -406,9 +360,7 @@ func (a *SortedStringArray) Clear() *SortedStringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Lock writing by callback function f.
|
||||
//
|
||||
// 使用自定义方法执行加锁修改操作。
|
||||
// LockFunc locks writing by callback function <f>.
|
||||
func (a *SortedStringArray) LockFunc(f func(array []string)) *SortedStringArray {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@ -416,9 +368,7 @@ func (a *SortedStringArray) LockFunc(f func(array []string)) *SortedStringArray
|
||||
return a
|
||||
}
|
||||
|
||||
// Lock reading by callback function f.
|
||||
//
|
||||
// 使用自定义方法执行加锁读取操作。
|
||||
// RLockFunc locks reading by callback function <f>.
|
||||
func (a *SortedStringArray) RLockFunc(f func(array []string)) *SortedStringArray {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -426,11 +376,10 @@ func (a *SortedStringArray) RLockFunc(f func(array []string)) *SortedStringArray
|
||||
return a
|
||||
}
|
||||
|
||||
// Merge two arrays. The parameter <array> can be any garray type or slice type.
|
||||
// The difference between Merge and Add is Add supports only specified slice type,
|
||||
// but Merge supports more variable types.
|
||||
//
|
||||
// 合并两个数组, 支持任意的garray数组类型及slice类型.
|
||||
// Merge merges <array> into current array.
|
||||
// The parameter <array> can be any garray or slice type.
|
||||
// The difference between Merge and Append is Append supports only specified slice type,
|
||||
// but Merge supports more parameter types.
|
||||
func (a *SortedStringArray) Merge(array interface{}) *SortedStringArray {
|
||||
switch v := array.(type) {
|
||||
case *Array: a.Add(gconv.Strings(v.Slice())...)
|
||||
@ -445,10 +394,9 @@ func (a *SortedStringArray) Merge(array interface{}) *SortedStringArray {
|
||||
return a
|
||||
}
|
||||
|
||||
// Chunks an array into arrays with size elements.
|
||||
// Chunk splits an array into multiple arrays,
|
||||
// the size of each array is determined by <size>.
|
||||
// The last chunk may contain less than size elements.
|
||||
//
|
||||
// 将一个数组分割成多个数组,其中每个数组的单元数目由size决定。最后一个数组的单元数目可能会少于size个。
|
||||
func (a *SortedStringArray) Chunk(size int) [][]string {
|
||||
if size < 1 {
|
||||
return nil
|
||||
@ -469,12 +417,9 @@ func (a *SortedStringArray) Chunk(size int) [][]string {
|
||||
return n
|
||||
}
|
||||
|
||||
// Extract a slice of the array(If in concurrent safe usage,
|
||||
// it returns a copy of the slice; else a pointer).
|
||||
// It returns the sequence of elements from the array array as specified
|
||||
// by the offset and length parameters.
|
||||
//
|
||||
// 返回根据offset和size参数所指定的数组中的一段序列。
|
||||
// SubSlice returns a slice of elements from the array as specified
|
||||
// by the <offset> and <size> parameters.
|
||||
// If in concurrent safe usage, it returns a copy of the slice; else a pointer.
|
||||
func (a *SortedStringArray) SubSlice(offset, size int) []string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -493,18 +438,14 @@ func (a *SortedStringArray) SubSlice(offset, size int) []string {
|
||||
}
|
||||
}
|
||||
|
||||
// Rand gets one random entry from array.
|
||||
//
|
||||
// 从数组中随机获得1个元素项(不删除)。
|
||||
// Rand randomly returns one item from array(no deleting).
|
||||
func (a *SortedStringArray) Rand() string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return a.array[grand.Intn(len(a.array))]
|
||||
}
|
||||
|
||||
// Rands gets one or more random entries from array(a copy).
|
||||
//
|
||||
// 从数组中随机拷贝size个元素项,构成slice返回。
|
||||
// Rands randomly returns <size> items from array(no deleting).
|
||||
func (a *SortedStringArray) Rands(size int) []string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -521,9 +462,7 @@ func (a *SortedStringArray) Rands(size int) []string {
|
||||
return n
|
||||
}
|
||||
|
||||
// Join array elements with a string.
|
||||
//
|
||||
// 使用glue字符串串连当前数组的元素项,构造成新的字符串返回。
|
||||
// Join joins array elements with a string <glue>.
|
||||
func (a *SortedStringArray) Join(glue string) string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
@ -535,4 +474,22 @@ func (a *SortedStringArray) Join(glue string) string {
|
||||
}
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// CountValues counts the number of occurrences of all values in the array.
|
||||
func (a *SortedStringArray) CountValues() map[string]int {
|
||||
m := make(map[string]int)
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
for _, v := range a.array {
|
||||
m[v]++
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// String returns current array as a string.
|
||||
func (a *SortedStringArray) String() string {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
return fmt.Sprint(a.array)
|
||||
}
|
||||
Reference in New Issue
Block a user