improve package garray

This commit is contained in:
John 2020-03-30 20:31:47 +08:00
parent 6fe6218505
commit 7e0fa8e0cd
18 changed files with 934 additions and 557 deletions

View File

@ -2,18 +2,20 @@ package main
import (
"fmt"
"github.com/gogf/gf/frame/g"
)
func main() {
c := g.Client()
c.SetCookieMap(g.MapStrStr{
"name": "john",
"score": "100",
})
if r, e := c.Get("http://127.0.0.1:8199/"); e != nil {
panic(e)
} else {
fmt.Println(r.ReadAllString())
}
func Test() (int, int) {
return 1, 1
}
func Assert(v1, v2, v3 interface{}) {
fmt.Println(v1)
}
func F(v ...interface{}) []interface{} {
return v
}
func main() {
Assert(F(Test()), 2, 3)
}

View File

@ -9,6 +9,7 @@ package garray
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/gogf/gf/internal/empty"
"github.com/gogf/gf/text/gstr"
@ -20,6 +21,7 @@ import (
"github.com/gogf/gf/util/grand"
)
// Array is a golang array with rich features.
type Array struct {
mu *rwmutex.RWMutex
array []interface{}
@ -94,21 +96,26 @@ func NewArrayFromCopy(array []interface{}, safe ...bool) *Array {
}
}
// Get returns the value of the specified index,
// the caller should notice the boundary of the array.
func (a *Array) Get(index int) interface{} {
// Get returns the value by the specified index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *Array) Get(index int) (value interface{}, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
value := a.array[index]
return value
if index < 0 || index >= len(a.array) {
return nil, false
}
return a.array[index], true
}
// Set sets value to specified index.
func (a *Array) Set(index int, value interface{}) *Array {
func (a *Array) Set(index int, value interface{}) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
a.array[index] = value
return a
return nil
}
// SetArray sets the underlying slice array with the given <array>.
@ -154,48 +161,60 @@ func (a *Array) SortFunc(less func(v1, v2 interface{}) bool) *Array {
}
// 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()
rear := append([]interface{}{}, a.array[index:]...)
a.array = append(a.array[0:index], value)
a.array = append(a.array, rear...)
return a
}
// 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()
rear := append([]interface{}{}, a.array[index+1:]...)
a.array = append(a.array[0:index+1], value)
a.array = append(a.array, rear...)
return a
}
// Remove removes an item by index.
func (a *Array) Remove(index int) interface{} {
func (a *Array) InsertBefore(index int, value interface{}) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return nil
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
// Determine array boundaries when deleting to improve deletion efficiency。
rear := append([]interface{}{}, a.array[index:]...)
a.array = append(a.array[0:index], value)
a.array = append(a.array, rear...)
return nil
}
// InsertAfter inserts the <value> to the back of <index>.
func (a *Array) InsertAfter(index int, value interface{}) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
rear := append([]interface{}{}, a.array[index+1:]...)
a.array = append(a.array[0:index+1], value)
a.array = append(a.array, rear...)
return nil
}
// Remove removes an item by index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *Array) Remove(index int) (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(index)
}
// doRemoveWithoutLock removes an item by index without lock.
func (a *Array) doRemoveWithoutLock(index int) (value interface{}, found bool) {
if index < 0 || index >= len(a.array) {
return nil, false
}
// Determine array boundaries when deleting to improve deletion efficiency.
if index == 0 {
value := a.array[0]
a.array = a.array[1:]
return value
return value, true
} else if index == len(a.array)-1 {
value := a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// 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]
value = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
return value
return value, true
}
// RemoveValue removes an item by value.
@ -226,64 +245,68 @@ func (a *Array) PushRight(value ...interface{}) *Array {
}
// PopRand randomly pops and return an item out of array.
func (a *Array) PopRand() interface{} {
return a.Remove(grand.Intn(len(a.array)))
// Note that if the array is empty, the <found> is false.
func (a *Array) PopRand() (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
// PopRands randomly pops and returns <size> items out of array.
func (a *Array) PopRands(size int) []interface{} {
a.mu.Lock()
defer a.mu.Unlock()
if size > len(a.array) {
size = len(a.array)
}
if size == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
size = len(a.array)
}
array := make([]interface{}, size)
for i := 0; i < size; i++ {
index := grand.Intn(len(a.array))
array[i] = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
return array
}
// PopLeft pops and returns an item from the beginning of array.
func (a *Array) PopLeft() interface{} {
// Note that if the array is empty, the <found> is false.
func (a *Array) PopLeft() (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
if len(a.array) == 0 {
return nil
return nil, false
}
value := a.array[0]
value = a.array[0]
a.array = a.array[1:]
return value
return value, true
}
// PopRight pops and returns an item from the end of array.
func (a *Array) PopRight() interface{} {
// Note that if the array is empty, the <found> is false.
func (a *Array) PopRight() (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
index := len(a.array) - 1
if index <= 0 {
return nil
return nil, false
}
value := a.array[index]
value = a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// 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()
length := len(a.array)
if length == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size > length {
size = length
if size >= len(a.array) {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[0:size]
a.array = a.array[size:]
@ -294,12 +317,14 @@ func (a *Array) PopLefts(size int) []interface{} {
func (a *Array) PopRights(size int) []interface{} {
a.mu.Lock()
defer a.mu.Unlock()
if len(a.array) == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
index := len(a.array) - size
if index < 0 {
index = 0
if index <= 0 {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[index:]
a.array = a.array[:index]
@ -529,11 +554,11 @@ func (a *Array) Merge(array interface{}) *Array {
// 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 {
func (a *Array) Fill(startIndex int, num int, value interface{}) error {
a.mu.Lock()
defer a.mu.Unlock()
if startIndex < 0 {
startIndex = 0
if startIndex < 0 || startIndex > len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", startIndex, len(a.array)))
}
for i := startIndex; i < startIndex+num; i++ {
if i > len(a.array)-1 {
@ -542,7 +567,7 @@ func (a *Array) Fill(startIndex int, num int, value interface{}) *Array {
a.array[i] = value
}
}
return a
return nil
}
// Chunk splits an array into multiple arrays,
@ -596,27 +621,27 @@ func (a *Array) Pad(size int, val interface{}) *Array {
}
// Rand randomly returns one item from array(no deleting).
func (a *Array) Rand() interface{} {
func (a *Array) Rand() (value interface{}, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
return a.array[grand.Intn(len(a.array))]
if len(a.array) == 0 {
return nil, false
}
return a.array[grand.Intn(len(a.array))], true
}
// Rands randomly returns <size> items from array(no deleting).
func (a *Array) Rands(size int) []interface{} {
a.mu.RLock()
defer a.mu.RUnlock()
if size > len(a.array) {
size = len(a.array)
if size <= 0 || len(a.array) == 0 {
return nil
}
n := make([]interface{}, size)
for i, v := range grand.Perm(len(a.array)) {
n[i] = a.array[v]
if i == size-1 {
break
}
array := make([]interface{}, size)
for i := 0; i < size; i++ {
array[i] = a.array[grand.Intn(len(a.array))]
}
return n
return array
}
// Shuffle randomly shuffles the array.

View File

@ -9,6 +9,7 @@ package garray
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"math"
"sort"
@ -77,21 +78,26 @@ func NewIntArrayFromCopy(array []int, safe ...bool) *IntArray {
}
}
// Get returns the value of the specified index,
// the caller should notice the boundary of the array.
func (a *IntArray) Get(index int) int {
// Get returns the value by the specified index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *IntArray) Get(index int) (value int, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
value := a.array[index]
return value
if index < 0 || index >= len(a.array) {
return 0, false
}
return a.array[index], true
}
// Set sets value to specified index.
func (a *IntArray) Set(index int, value int) *IntArray {
func (a *IntArray) Set(index int, value int) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
a.array[index] = value
return a
return nil
}
// SetArray sets the underlying slice array with the given <array>.
@ -127,8 +133,7 @@ func (a *IntArray) Sum() (sum int) {
}
// Sort sorts the array in increasing order.
// The parameter <reverse> controls whether sort
// in increasing order(default) or decreasing order
// The parameter <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()
@ -156,57 +161,68 @@ func (a *IntArray) SortFunc(less func(v1, v2 int) bool) *IntArray {
}
// 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()
rear := append([]int{}, a.array[index:]...)
a.array = append(a.array[0:index], value)
a.array = append(a.array, rear...)
return a
}
// 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()
rear := append([]int{}, a.array[index+1:]...)
a.array = append(a.array[0:index+1], value)
a.array = append(a.array, rear...)
return a
}
// Remove removes an item by index.
// Note that if the index is out of range of array, it returns 0.
func (a *IntArray) Remove(index int) int {
func (a *IntArray) InsertBefore(index int, value int) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return 0
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
rear := append([]int{}, a.array[index:]...)
a.array = append(a.array[0:index], value)
a.array = append(a.array, rear...)
return nil
}
// InsertAfter inserts the <value> to the back of <index>.
func (a *IntArray) InsertAfter(index int, value int) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
rear := append([]int{}, a.array[index+1:]...)
a.array = append(a.array[0:index+1], value)
a.array = append(a.array, rear...)
return nil
}
// Remove removes an item by index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *IntArray) Remove(index int) (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(index)
}
// doRemoveWithoutLock removes an item by index without lock.
func (a *IntArray) doRemoveWithoutLock(index int) (value int, found bool) {
if index < 0 || index >= len(a.array) {
return 0, false
}
// Determine array boundaries when deleting to improve deletion efficiency.
if index == 0 {
value := a.array[0]
a.array = a.array[1:]
return value
return value, true
} else if index == len(a.array)-1 {
value := a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// 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]
value = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
return value
return value, true
}
// RemoveValue removes an item by value.
// It returns true if value is found in the array, or else false if not found.
func (a *IntArray) RemoveValue(value int) bool {
if i := a.Search(value); i != -1 {
a.Remove(i)
return true
_, found := a.Remove(i)
return found
}
return false
}
@ -229,72 +245,72 @@ func (a *IntArray) PushRight(value ...int) *IntArray {
}
// PopLeft pops and returns an item from the beginning of array.
// Note that if the array is empty, it returns 0.
// Be very careful when use this function in loop statement.
// You can use IsEmpty() of Len() == 0 checks if this array empty.
func (a *IntArray) PopLeft() int {
// Note that if the array is empty, the <found> is false.
func (a *IntArray) PopLeft() (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
if len(a.array) == 0 {
return 0
return 0, false
}
value := a.array[0]
value = a.array[0]
a.array = a.array[1:]
return value
return value, true
}
// PopRight pops and returns an item from the end of array.
// Note that if the array is empty, it returns 0.
// Be very careful when use this function in loop statement.
// You can use IsEmpty() of Len() == 0 checks if this array empty.
func (a *IntArray) PopRight() int {
// Note that if the array is empty, the <found> is false.
func (a *IntArray) PopRight() (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
index := len(a.array) - 1
if index <= 0 {
return 0
return 0, false
}
value := a.array[index]
value = a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// PopRand randomly pops and return an item out of array.
// Be very careful when use this function in loop statement.
// You can use IsEmpty() of Len() == 0 checks if this array empty.
func (a *IntArray) PopRand() int {
return a.Remove(grand.Intn(len(a.array)))
// Note that if the array is empty, the <found> is false.
func (a *IntArray) PopRand() (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
// PopRands randomly pops and returns <size> items out of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *IntArray) PopRands(size int) []int {
a.mu.Lock()
defer a.mu.Unlock()
if size > len(a.array) {
size = len(a.array)
}
if size == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
size = len(a.array)
}
array := make([]int, size)
for i := 0; i < size; i++ {
index := grand.Intn(len(a.array))
array[i] = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
return array
}
// PopLefts pops and returns <size> items from the beginning of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *IntArray) PopLefts(size int) []int {
a.mu.Lock()
defer a.mu.Unlock()
length := len(a.array)
if length == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size > length {
size = length
if size >= len(a.array) {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[0:size]
a.array = a.array[size:]
@ -302,15 +318,19 @@ func (a *IntArray) PopLefts(size int) []int {
}
// PopRights pops and returns <size> items from the end of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *IntArray) PopRights(size int) []int {
a.mu.Lock()
defer a.mu.Unlock()
if len(a.array) == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
index := len(a.array) - size
if index < 0 {
index = 0
if index <= 0 {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[index:]
a.array = a.array[:index]
@ -535,11 +555,11 @@ func (a *IntArray) Merge(array interface{}) *IntArray {
// 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 {
func (a *IntArray) Fill(startIndex int, num int, value int) error {
a.mu.Lock()
defer a.mu.Unlock()
if startIndex < 0 {
startIndex = 0
if startIndex < 0 || startIndex > len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", startIndex, len(a.array)))
}
for i := startIndex; i < startIndex+num; i++ {
if i > len(a.array)-1 {
@ -548,7 +568,7 @@ func (a *IntArray) Fill(startIndex int, num int, value int) *IntArray {
a.array[i] = value
}
}
return a
return nil
}
// Chunk splits an array into multiple arrays,
@ -602,27 +622,27 @@ func (a *IntArray) Pad(size int, value int) *IntArray {
}
// Rand randomly returns one item from array(no deleting).
func (a *IntArray) Rand() int {
func (a *IntArray) Rand() (value int, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
return a.array[grand.Intn(len(a.array))]
if len(a.array) == 0 {
return 0, false
}
return a.array[grand.Intn(len(a.array))], true
}
// Rands randomly returns <size> items from array(no deleting).
func (a *IntArray) Rands(size int) []int {
a.mu.RLock()
defer a.mu.RUnlock()
if size > len(a.array) {
size = len(a.array)
if size <= 0 || len(a.array) == 0 {
return nil
}
n := make([]int, size)
for i, v := range grand.Perm(len(a.array)) {
n[i] = a.array[v]
if i == size-1 {
break
}
array := make([]int, size)
for i := 0; i < size; i++ {
array[i] = a.array[grand.Intn(len(a.array))]
}
return n
return array
}
// Shuffle randomly shuffles the array.

View File

@ -9,6 +9,8 @@ package garray
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/gogf/gf/text/gstr"
"math"
"sort"
@ -63,21 +65,26 @@ func NewStrArrayFromCopy(array []string, safe ...bool) *StrArray {
}
}
// Get returns the value of the specified index,
// the caller should notice the boundary of the array.
func (a *StrArray) Get(index int) string {
// Get returns the value by the specified index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *StrArray) Get(index int) (value string, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
value := a.array[index]
return value
if index < 0 || index >= len(a.array) {
return "", false
}
return a.array[index], true
}
// Set sets value to specified index.
func (a *StrArray) Set(index int, value string) *StrArray {
func (a *StrArray) Set(index int, value string) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
a.array[index] = value
return a
return nil
}
// SetArray sets the underlying slice array with the given <array>.
@ -142,57 +149,68 @@ func (a *StrArray) SortFunc(less func(v1, v2 string) bool) *StrArray {
}
// InsertBefore inserts the <value> to the front of <index>.
func (a *StrArray) InsertBefore(index int, value string) *StrArray {
a.mu.Lock()
defer a.mu.Unlock()
rear := append([]string{}, a.array[index:]...)
a.array = append(a.array[0:index], value)
a.array = append(a.array, rear...)
return a
}
// InsertAfter inserts the <value> to the back of <index>.
func (a *StrArray) InsertAfter(index int, value string) *StrArray {
a.mu.Lock()
defer a.mu.Unlock()
rear := append([]string{}, a.array[index+1:]...)
a.array = append(a.array[0:index+1], value)
a.array = append(a.array, rear...)
return a
}
// Remove removes an item by index.
// Note that if the index is out of range of array, it returns an empty string.
func (a *StrArray) Remove(index int) string {
func (a *StrArray) InsertBefore(index int, value string) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return ""
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
// Determine array boundaries when deleting to improve deletion efficiency。
rear := append([]string{}, a.array[index:]...)
a.array = append(a.array[0:index], value)
a.array = append(a.array, rear...)
return nil
}
// InsertAfter inserts the <value> to the back of <index>.
func (a *StrArray) InsertAfter(index int, value string) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
rear := append([]string{}, a.array[index+1:]...)
a.array = append(a.array[0:index+1], value)
a.array = append(a.array, rear...)
return nil
}
// Remove removes an item by index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *StrArray) Remove(index int) (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(index)
}
// doRemoveWithoutLock removes an item by index without lock.
func (a *StrArray) doRemoveWithoutLock(index int) (value string, found bool) {
if index < 0 || index >= len(a.array) {
return "", false
}
// Determine array boundaries when deleting to improve deletion efficiency.
if index == 0 {
value := a.array[0]
a.array = a.array[1:]
return value
return value, true
} else if index == len(a.array)-1 {
value := a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// 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]
value = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
return value
return value, true
}
// RemoveValue removes an item by value.
// It returns true if value is found in the array, or else false if not found.
func (a *StrArray) RemoveValue(value string) bool {
if i := a.Search(value); i != -1 {
a.Remove(i)
return true
_, found := a.Remove(i)
return found
}
return false
}
@ -215,89 +233,92 @@ func (a *StrArray) PushRight(value ...string) *StrArray {
}
// PopLeft pops and returns an item from the beginning of array.
// Note that if the array is empty, it returns an empty string.
// Be very careful when use this function in loop statement.
// You can use IsEmpty() of Len() == 0 checks if this array empty.
func (a *StrArray) PopLeft() string {
// Note that if the array is empty, the <found> is false.
func (a *StrArray) PopLeft() (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
if len(a.array) == 0 {
return ""
return "", false
}
value := a.array[0]
value = a.array[0]
a.array = a.array[1:]
return value
return value, true
}
// PopRight pops and returns an item from the end of array.
// Note that if the array is empty, it returns an empty string.
// Be very careful when use this function in loop statement.
// You can use IsEmpty() of Len() == 0 checks if this array empty.
func (a *StrArray) PopRight() string {
// Note that if the array is empty, the <found> is false.
func (a *StrArray) PopRight() (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
index := len(a.array) - 1
if index <= 0 {
return ""
return "", false
}
value := a.array[index]
value = a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// PopRand randomly pops and return an item out of array.
// Note that if the array is empty, it returns an empty string.
// Be very careful when use this function in loop statement.
// You can use IsEmpty() of Len() == 0 checks if this array empty.
func (a *StrArray) PopRand() string {
return a.Remove(grand.Intn(len(a.array)))
// Note that if the array is empty, the <found> is false.
func (a *StrArray) PopRand() (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
// PopRands randomly pops and returns <size> items out of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *StrArray) PopRands(size int) []string {
a.mu.Lock()
defer a.mu.Unlock()
if size > len(a.array) {
size = len(a.array)
}
if size == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
size = len(a.array)
}
array := make([]string, size)
for i := 0; i < size; i++ {
index := grand.Intn(len(a.array))
array[i] = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
return array
}
// PopLefts pops and returns <size> items from the beginning of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *StrArray) PopLefts(size int) []string {
a.mu.Lock()
defer a.mu.Unlock()
length := len(a.array)
if size > length {
size = length
}
if size == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[0:size]
a.array = a.array[size:]
return value
}
// PopRights pops and returns <size> items from the end of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *StrArray) PopRights(size int) []string {
a.mu.Lock()
defer a.mu.Unlock()
if len(a.array) == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
index := len(a.array) - size
if index < 0 {
index = 0
if index <= 0 {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[index:]
a.array = a.array[:index]
@ -525,11 +546,11 @@ func (a *StrArray) Merge(array interface{}) *StrArray {
// Fill fills an array with num entries of the value <value>,
// keys starting at the <startIndex> parameter.
func (a *StrArray) Fill(startIndex int, num int, value string) *StrArray {
func (a *StrArray) Fill(startIndex int, num int, value string) error {
a.mu.Lock()
defer a.mu.Unlock()
if startIndex < 0 {
startIndex = 0
if startIndex < 0 || startIndex > len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", startIndex, len(a.array)))
}
for i := startIndex; i < startIndex+num; i++ {
if i > len(a.array)-1 {
@ -538,7 +559,7 @@ func (a *StrArray) Fill(startIndex int, num int, value string) *StrArray {
a.array[i] = value
}
}
return a
return nil
}
// Chunk splits an array into multiple arrays,
@ -592,27 +613,27 @@ func (a *StrArray) Pad(size int, value string) *StrArray {
}
// Rand randomly returns one item from array(no deleting).
func (a *StrArray) Rand() string {
func (a *StrArray) Rand() (value string, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
return a.array[grand.Intn(len(a.array))]
if len(a.array) == 0 {
return "", false
}
return a.array[grand.Intn(len(a.array))], true
}
// Rands randomly returns <size> items from array(no deleting).
func (a *StrArray) Rands(size int) []string {
a.mu.RLock()
defer a.mu.RUnlock()
if size > len(a.array) {
size = len(a.array)
if size <= 0 || len(a.array) == 0 {
return nil
}
n := make([]string, size)
for i, v := range grand.Perm(len(a.array)) {
n[i] = a.array[v]
if i == size-1 {
break
}
array := make([]string, size)
for i := 0; i < size; i++ {
array[i] = a.array[grand.Intn(len(a.array))]
}
return n
return array
}
// Shuffle randomly shuffles the array.

View File

@ -148,38 +148,46 @@ func (a *SortedArray) Add(values ...interface{}) *SortedArray {
return a
}
// Get returns the value of the specified index,
// the caller should notice the boundary of the array.
func (a *SortedArray) Get(index int) interface{} {
// Get returns the value by the specified index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *SortedArray) Get(index int) (value interface{}, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
value := a.array[index]
return value
if index < 0 || index >= len(a.array) {
return nil, false
}
return a.array[index], true
}
// Remove removes an item by index.
func (a *SortedArray) Remove(index int) interface{} {
// If the given <index> is out of range of the array, the <found> is false.
func (a *SortedArray) Remove(index int) (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(index)
}
// doRemoveWithoutLock removes an item by index without lock.
func (a *SortedArray) doRemoveWithoutLock(index int) (value interface{}, found bool) {
if index < 0 || index >= len(a.array) {
return nil
return nil, false
}
// Determine array boundaries when deleting to improve deletion efficiency.
if index == 0 {
value := a.array[0]
a.array = a.array[1:]
return value
return value, true
} else if index == len(a.array)-1 {
value := a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// 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]
value = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
return value
return value, true
}
// RemoveValue removes an item by value.
@ -193,50 +201,53 @@ func (a *SortedArray) RemoveValue(value interface{}) bool {
}
// PopLeft pops and returns an item from the beginning of array.
func (a *SortedArray) PopLeft() interface{} {
// Note that if the array is empty, the <found> is false.
func (a *SortedArray) PopLeft() (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
if len(a.array) == 0 {
return nil
return nil, false
}
value := a.array[0]
value = a.array[0]
a.array = a.array[1:]
return value
return value, true
}
// PopRight pops and returns an item from the end of array.
func (a *SortedArray) PopRight() interface{} {
// Note that if the array is empty, the <found> is false.
func (a *SortedArray) PopRight() (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
index := len(a.array) - 1
if index <= 0 {
return nil
return nil, false
}
value := a.array[index]
value = a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// PopRand randomly pops and return an item out of array.
func (a *SortedArray) PopRand() interface{} {
return a.Remove(grand.Intn(len(a.array)))
// Note that if the array is empty, the <found> is false.
func (a *SortedArray) PopRand() (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
// PopRands randomly pops and returns <size> items out of array.
func (a *SortedArray) PopRands(size int) []interface{} {
a.mu.Lock()
defer a.mu.Unlock()
if size > len(a.array) {
size = len(a.array)
}
if size == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
size = len(a.array)
}
array := make([]interface{}, size)
for i := 0; i < size; i++ {
index := grand.Intn(len(a.array))
array[i] = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
return array
}
@ -245,13 +256,14 @@ func (a *SortedArray) PopRands(size int) []interface{} {
func (a *SortedArray) PopLefts(size int) []interface{} {
a.mu.Lock()
defer a.mu.Unlock()
length := len(a.array)
if size > length {
size = length
}
if size == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[0:size]
a.array = a.array[size:]
return value
@ -261,12 +273,14 @@ func (a *SortedArray) PopLefts(size int) []interface{} {
func (a *SortedArray) PopRights(size int) []interface{} {
a.mu.Lock()
defer a.mu.Unlock()
if len(a.array) == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
index := len(a.array) - size
if index < 0 {
index = 0
if index <= 0 {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[index:]
a.array = a.array[:index]
@ -554,27 +568,27 @@ func (a *SortedArray) Chunk(size int) [][]interface{} {
}
// Rand randomly returns one item from array(no deleting).
func (a *SortedArray) Rand() interface{} {
func (a *SortedArray) Rand() (value interface{}, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
return a.array[grand.Intn(len(a.array))]
if len(a.array) == 0 {
return nil, false
}
return a.array[grand.Intn(len(a.array))], true
}
// Rands randomly returns <size> items from array(no deleting).
func (a *SortedArray) Rands(size int) []interface{} {
a.mu.RLock()
defer a.mu.RUnlock()
if size > len(a.array) {
size = len(a.array)
if size <= 0 || len(a.array) == 0 {
return nil
}
n := make([]interface{}, size)
for i, v := range grand.Perm(len(a.array)) {
n[i] = a.array[v]
if i == size-1 {
break
}
array := make([]interface{}, size)
for i := 0; i < size; i++ {
array[i] = a.array[grand.Intn(len(a.array))]
}
return n
return array
}
// Join joins array elements with a string <glue>.

View File

@ -133,135 +133,145 @@ func (a *SortedIntArray) Add(values ...int) *SortedIntArray {
return a
}
// Get returns the value of the specified index,
// the caller should notice the boundary of the array.
func (a *SortedIntArray) Get(index int) int {
// Get returns the value by the specified index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *SortedIntArray) Get(index int) (value int, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
value := a.array[index]
return value
if index < 0 || index >= len(a.array) {
return 0, false
}
return a.array[index], true
}
// Remove removes an item by index.
// Note that if the index is out of range of array, it returns 0.
func (a *SortedIntArray) Remove(index int) int {
// If the given <index> is out of range of the array, the <found> is false.
func (a *SortedIntArray) Remove(index int) (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(index)
}
// doRemoveWithoutLock removes an item by index without lock.
func (a *SortedIntArray) doRemoveWithoutLock(index int) (value int, found bool) {
if index < 0 || index >= len(a.array) {
return 0
return 0, false
}
// Determine array boundaries when deleting to improve deletion efficiency.
if index == 0 {
value := a.array[0]
a.array = a.array[1:]
return value
return value, true
} else if index == len(a.array)-1 {
value := a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// 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]
value = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
return value
return value, true
}
// RemoveValue removes an item by value.
// It returns true if value is found in the array, or else false if not found.
func (a *SortedIntArray) RemoveValue(value int) bool {
if i := a.Search(value); i != -1 {
a.Remove(i)
return true
_, found := a.Remove(i)
return found
}
return false
}
// PopLeft pops and returns an item from the beginning of array.
// Note that if the array is empty, it returns 0.
// Be very careful when use this function in loop statement.
// You can use IsEmpty() of Len() == 0 checks if this array empty.
func (a *SortedIntArray) PopLeft() int {
// Note that if the array is empty, the <found> is false.
func (a *SortedIntArray) PopLeft() (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
if len(a.array) == 0 {
return 0
return 0, false
}
value := a.array[0]
value = a.array[0]
a.array = a.array[1:]
return value
return value, true
}
// PopRight pops and returns an item from the end of array.
// Note that if the array is empty, it returns 0.
// Be very careful when use this function in loop statement.
// You can use IsEmpty() of Len() == 0 checks if this array empty.
func (a *SortedIntArray) PopRight() int {
// Note that if the array is empty, the <found> is false.
func (a *SortedIntArray) PopRight() (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
index := len(a.array) - 1
if index <= 0 {
return 0
return 0, false
}
value := a.array[index]
value = a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// PopRand randomly pops and return an item out of array.
// Note that if the array is empty, it returns 0.
// Be very careful when use this function in loop statement.
// You can use IsEmpty() of Len() == 0 checks if this array empty.
func (a *SortedIntArray) PopRand() int {
return a.Remove(grand.Intn(len(a.array)))
// Note that if the array is empty, the <found> is false.
func (a *SortedIntArray) PopRand() (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
// PopRands randomly pops and returns <size> items out of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *SortedIntArray) PopRands(size int) []int {
a.mu.Lock()
defer a.mu.Unlock()
if size > len(a.array) {
size = len(a.array)
}
if size == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
size = len(a.array)
}
array := make([]int, size)
for i := 0; i < size; i++ {
index := grand.Intn(len(a.array))
array[i] = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
return array
}
// PopLefts pops and returns <size> items from the beginning of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *SortedIntArray) PopLefts(size int) []int {
a.mu.Lock()
defer a.mu.Unlock()
length := len(a.array)
if size > length {
size = length
}
if size == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[0:size]
a.array = a.array[size:]
return value
}
// PopRights pops and returns <size> items from the end of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *SortedIntArray) PopRights(size int) []int {
a.mu.Lock()
defer a.mu.Unlock()
if len(a.array) == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
index := len(a.array) - size
if index < 0 {
index = 0
if index <= 0 {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[index:]
a.array = a.array[:index]
@ -555,27 +565,27 @@ func (a *SortedIntArray) Chunk(size int) [][]int {
}
// Rand randomly returns one item from array(no deleting).
func (a *SortedIntArray) Rand() int {
func (a *SortedIntArray) Rand() (value int, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
return a.array[grand.Intn(len(a.array))]
if len(a.array) == 0 {
return 0, false
}
return a.array[grand.Intn(len(a.array))], true
}
// Rands randomly returns <size> items from array(no deleting).
func (a *SortedIntArray) Rands(size int) []int {
a.mu.RLock()
defer a.mu.RUnlock()
if size > len(a.array) {
size = len(a.array)
if size <= 0 || len(a.array) == 0 {
return nil
}
n := make([]int, size)
for i, v := range grand.Perm(len(a.array)) {
n[i] = a.array[v]
if i == size-1 {
break
}
array := make([]int, size)
for i := 0; i < size; i++ {
array[i] = a.array[grand.Intn(len(a.array))]
}
return n
return array
}
// Join joins array elements with a string <glue>.

View File

@ -118,39 +118,46 @@ func (a *SortedStrArray) Add(values ...string) *SortedStrArray {
return a
}
// Get returns the value of the specified index,
// the caller should notice the boundary of the array.
func (a *SortedStrArray) Get(index int) string {
// Get returns the value by the specified index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *SortedStrArray) Get(index int) (value string, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
value := a.array[index]
return value
if index < 0 || index >= len(a.array) {
return "", false
}
return a.array[index], true
}
// Remove removes an item by index.
// Note that if the index is out of range of array, it returns an empty string.
func (a *SortedStrArray) Remove(index int) string {
// If the given <index> is out of range of the array, the <found> is false.
func (a *SortedStrArray) Remove(index int) (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(index)
}
// doRemoveWithoutLock removes an item by index without lock.
func (a *SortedStrArray) doRemoveWithoutLock(index int) (value string, found bool) {
if index < 0 || index >= len(a.array) {
return ""
return "", false
}
// Determine array boundaries when deleting to improve deletion efficiency.
if index == 0 {
value := a.array[0]
a.array = a.array[1:]
return value
return value, true
} else if index == len(a.array)-1 {
value := a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// 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]
value = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
return value
return value, true
}
// RemoveValue removes an item by value.
@ -164,89 +171,92 @@ func (a *SortedStrArray) RemoveValue(value string) bool {
}
// PopLeft pops and returns an item from the beginning of array.
// Note that if the array is empty, it returns an empty string.
// Be very careful when use this function in loop statement.
// You can use IsEmpty() of Len() == 0 checks if this array empty.
func (a *SortedStrArray) PopLeft() string {
// Note that if the array is empty, the <found> is false.
func (a *SortedStrArray) PopLeft() (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
if len(a.array) == 0 {
return ""
return "", false
}
value := a.array[0]
value = a.array[0]
a.array = a.array[1:]
return value
return value, true
}
// PopRight pops and returns an item from the end of array.
// Note that if the array is empty, it returns an empty string.
// Be very careful when use this function in loop statement.
// You can use IsEmpty() of Len() == 0 checks if this array empty.
func (a *SortedStrArray) PopRight() string {
// Note that if the array is empty, the <found> is false.
func (a *SortedStrArray) PopRight() (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
index := len(a.array) - 1
if index <= 0 {
return ""
return "", false
}
value := a.array[index]
value = a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// PopRand randomly pops and return an item out of array.
// Note that if the array is empty, it returns an empty string.
// Be very careful when use this function in loop statement.
// You can use IsEmpty() of Len() == 0 checks if this array empty.
func (a *SortedStrArray) PopRand() string {
return a.Remove(grand.Intn(len(a.array)))
// Note that if the array is empty, the <found> is false.
func (a *SortedStrArray) PopRand() (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
// PopRands randomly pops and returns <size> items out of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *SortedStrArray) PopRands(size int) []string {
a.mu.Lock()
defer a.mu.Unlock()
if size > len(a.array) {
size = len(a.array)
}
if size == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
size = len(a.array)
}
array := make([]string, size)
for i := 0; i < size; i++ {
index := grand.Intn(len(a.array))
array[i] = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
return array
}
// PopLefts pops and returns <size> items from the beginning of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *SortedStrArray) PopLefts(size int) []string {
a.mu.Lock()
defer a.mu.Unlock()
length := len(a.array)
if size > length {
size = length
}
if size == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[0:size]
a.array = a.array[size:]
return value
}
// PopRights pops and returns <size> items from the end of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *SortedStrArray) PopRights(size int) []string {
a.mu.Lock()
defer a.mu.Unlock()
if len(a.array) == 0 {
if size <= 0 || len(a.array) == 0 {
return nil
}
index := len(a.array) - size
if index < 0 {
index = 0
if index <= 0 {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[index:]
a.array = a.array[:index]
@ -540,27 +550,27 @@ func (a *SortedStrArray) Chunk(size int) [][]string {
}
// Rand randomly returns one item from array(no deleting).
func (a *SortedStrArray) Rand() string {
func (a *SortedStrArray) Rand() (value string, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
return a.array[grand.Intn(len(a.array))]
if len(a.array) == 0 {
return "", false
}
return a.array[grand.Intn(len(a.array))], true
}
// Rands randomly returns <size> items from array(no deleting).
func (a *SortedStrArray) Rands(size int) []string {
a.mu.RLock()
defer a.mu.RUnlock()
if size > len(a.array) {
size = len(a.array)
if size <= 0 || len(a.array) == 0 {
return nil
}
n := make([]string, size)
for i, v := range grand.Perm(len(a.array)) {
n[i] = a.array[v]
if i == size-1 {
break
}
array := make([]string, size)
for i := 0; i < size; i++ {
array[i] = a.array[grand.Intn(len(a.array))]
}
return n
return array
}
// Join joins array elements with a string <glue>.

View File

@ -61,7 +61,7 @@ func Example_basic() {
// Output:
// 10
// [0 1 2 3 4 5 6 7 8 9]
// 6
// 6 true
// true
// false
// [0 1 2 3 4 5 6 7 8 9 10 11]
@ -95,9 +95,9 @@ func Example_popItem() {
fmt.Println(array.PopRights(2))
// Output:
// 1
// 1 true
// [2 3]
// 9
// 9 true
// [7 8]
}

View File

@ -28,17 +28,38 @@ func Test_Array_Basic(t *testing.T) {
t.Assert(array.Slice(), expect)
t.Assert(array.Interfaces(), expect)
array.Set(0, 100)
t.Assert(array.Get(0), 100)
t.Assert(array.Get(1), 1)
v, ok := array.Get(0)
t.Assert(v, 100)
t.Assert(ok, true)
v, ok = array.Get(1)
t.Assert(v, 1)
t.Assert(ok, true)
t.Assert(array.Search(100), 0)
t.Assert(array3.Search(100), -1)
t.Assert(array.Contains(100), true)
t.Assert(array.Remove(0), 100)
t.Assert(array.Remove(-1), nil)
t.Assert(array.Remove(100000), nil)
t.Assert(array2.Remove(3), 3)
t.Assert(array2.Remove(1), 1)
v, ok = array.Remove(0)
t.Assert(v, 100)
t.Assert(ok, true)
v, ok = array.Remove(-1)
t.Assert(v, nil)
t.Assert(ok, false)
v, ok = array.Remove(100000)
t.Assert(v, nil)
t.Assert(ok, false)
v, ok = array2.Remove(3)
t.Assert(v, 3)
t.Assert(ok, true)
v, ok = array2.Remove(1)
t.Assert(v, 1)
t.Assert(ok, true)
t.Assert(array.Contains(100), false)
array.Append(4)
@ -85,10 +106,23 @@ func TestArray_PushAndPop(t *testing.T) {
expect := []interface{}{0, 1, 2, 3}
array := garray.NewArrayFrom(expect)
t.Assert(array.Slice(), expect)
t.Assert(array.PopLeft(), 0)
t.Assert(array.PopRight(), 3)
t.AssertIN(array.PopRand(), []interface{}{1, 2})
t.AssertIN(array.PopRand(), []interface{}{1, 2})
v, ok := array.PopLeft()
t.Assert(v, 0)
t.Assert(ok, true)
v, ok = array.PopRight()
t.Assert(v, 3)
t.Assert(ok, true)
v, ok = array.PopRand()
t.AssertIN(v, []interface{}{1, 2})
t.Assert(ok, true)
v, ok = array.PopRand()
t.AssertIN(v, []interface{}{1, 2})
t.Assert(ok, true)
t.Assert(array.Len(), 0)
array.PushLeft(1).PushRight(2)
t.Assert(array.Slice(), []interface{}{1, 2})
@ -106,11 +140,19 @@ func TestArray_PopRands(t *testing.T) {
func TestArray_PopLeftsAndPopRights(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.New()
t.Assert(array.PopLeft(), nil)
v, ok := array.PopLeft()
t.Assert(v, nil)
t.Assert(ok, false)
t.Assert(array.PopLefts(10), nil)
t.Assert(array.PopRight(), nil)
v, ok = array.PopRight()
t.Assert(v, nil)
t.Assert(ok, false)
t.Assert(array.PopRights(10), nil)
t.Assert(array.PopRand(), nil)
v, ok = array.PopRand()
t.Assert(v, nil)
t.Assert(ok, false)
t.Assert(array.PopRands(10), nil)
})
@ -185,9 +227,15 @@ func TestArray_Fill(t *testing.T) {
a2 := []interface{}{0}
array1 := garray.NewArrayFrom(a1)
array2 := garray.NewArrayFrom(a2, true)
t.Assert(array1.Fill(1, 2, 100).Slice(), []interface{}{0, 100, 100})
t.Assert(array2.Fill(0, 2, 100).Slice(), []interface{}{100, 100})
t.Assert(array2.Fill(-1, 2, 100).Slice(), []interface{}{100, 100})
t.Assert(array1.Fill(1, 2, 100), nil)
t.Assert(array1.Slice(), []interface{}{0, 100, 100})
t.Assert(array2.Fill(0, 2, 100), nil)
t.Assert(array2.Slice(), []interface{}{100, 100})
t.AssertNE(array2.Fill(-1, 2, 100), nil)
t.Assert(array2.Slice(), []interface{}{100, 100})
})
}
@ -263,14 +311,15 @@ func TestArray_Rand(t *testing.T) {
a1 := []interface{}{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewArrayFrom(a1)
t.Assert(len(array1.Rands(2)), 2)
t.Assert(len(array1.Rands(10)), 7)
t.Assert(len(array1.Rands(10)), 10)
t.AssertIN(array1.Rands(1)[0], a1)
})
gtest.C(t, func(t *gtest.T) {
s1 := []interface{}{"a", "b", "c", "d"}
a1 := garray.NewArrayFrom(s1)
i1 := a1.Rand()
i1, ok := a1.Rand()
t.Assert(ok, true)
t.Assert(a1.Contains(i1), true)
t.Assert(a1.Len(), 4)
})

View File

@ -29,14 +29,31 @@ func Test_IntArray_Basic(t *testing.T) {
t.Assert(array.Slice(), expect)
t.Assert(array.Interfaces(), expect)
array.Set(0, 100)
t.Assert(array.Get(0), 100)
t.Assert(array.Get(1), 1)
v, ok := array.Get(0)
t.Assert(v, 100)
t.Assert(ok, true)
v, ok = array.Get(1)
t.Assert(v, 1)
t.Assert(ok, true)
t.Assert(array.Search(100), 0)
t.Assert(array2.Search(100), -1)
t.Assert(array.Contains(100), true)
t.Assert(array.Remove(0), 100)
t.Assert(array.Remove(-1), 0)
t.Assert(array.Remove(100000), 0)
v, ok = array.Remove(0)
t.Assert(v, 100)
t.Assert(ok, true)
v, ok = array.Remove(-1)
t.Assert(v, 0)
t.Assert(ok, false)
v, ok = array.Remove(100000)
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.Contains(100), false)
array.Append(4)
t.Assert(array.Len(), 4)
@ -81,10 +98,27 @@ func TestIntArray_PushAndPop(t *testing.T) {
expect := []int{0, 1, 2, 3}
array := garray.NewIntArrayFrom(expect)
t.Assert(array.Slice(), expect)
t.Assert(array.PopLeft(), 0)
t.Assert(array.PopRight(), 3)
t.AssertIN(array.PopRand(), []int{1, 2})
t.AssertIN(array.PopRand(), []int{1, 2})
v, ok := array.PopLeft()
t.Assert(v, 0)
t.Assert(ok, true)
v, ok = array.PopRight()
t.Assert(v, 3)
t.Assert(ok, true)
v, ok = array.PopRand()
t.AssertIN(v, []int{1, 2})
t.Assert(ok, true)
v, ok = array.PopRand()
t.AssertIN(v, []int{1, 2})
t.Assert(ok, true)
v, ok = array.PopRand()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.Len(), 0)
array.PushLeft(1).PushRight(2)
t.Assert(array.Slice(), []int{1, 2})
@ -94,11 +128,23 @@ func TestIntArray_PushAndPop(t *testing.T) {
func TestIntArray_PopLeftsAndPopRights(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewIntArray()
t.Assert(array.PopLeft(), 0)
v, ok := array.PopLeft()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.PopLefts(10), nil)
t.Assert(array.PopRight(), 0)
v, ok = array.PopRight()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.PopRights(10), nil)
t.Assert(array.PopRand(), 0)
v, ok = array.PopRand()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.PopRands(10), nil)
})
@ -173,9 +219,14 @@ func TestIntArray_Fill(t *testing.T) {
a2 := []int{0}
array1 := garray.NewIntArrayFrom(a1)
array2 := garray.NewIntArrayFrom(a2)
t.Assert(array1.Fill(1, 2, 100).Slice(), []int{0, 100, 100})
t.Assert(array2.Fill(0, 2, 100).Slice(), []int{100, 100})
t.Assert(array2.Fill(-1, 2, 100).Slice(), []int{100, 100})
t.Assert(array1.Fill(1, 2, 100), nil)
t.Assert(array1.Slice(), []int{0, 100, 100})
t.Assert(array2.Fill(0, 2, 100), nil)
t.Assert(array2.Slice(), []int{100, 100})
t.AssertNE(array2.Fill(-1, 2, 100), nil)
t.Assert(array2.Slice(), []int{100, 100})
})
}
@ -259,9 +310,12 @@ func TestIntArray_Rand(t *testing.T) {
a1 := []int{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewIntArrayFrom(a1)
t.Assert(len(array1.Rands(2)), 2)
t.Assert(len(array1.Rands(10)), 7)
t.Assert(len(array1.Rands(10)), 10)
t.AssertIN(array1.Rands(1)[0], a1)
t.AssertIN(array1.Rand(), a1)
v, ok := array1.Rand()
t.AssertIN(v, a1)
t.Assert(ok, true)
})
}
@ -358,7 +412,9 @@ func TestArray_Get(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 5}
array1 := garray.NewIntArrayFrom(a1)
t.Assert(array1.Get(2), 3)
v, ok := array1.Get(2)
t.Assert(v, 3)
t.Assert(ok, true)
t.Assert(array1.Len(), 4)
})
}
@ -395,16 +451,19 @@ func TestIntArray_Remove(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 5, 4}
array1 := garray.NewIntArrayFrom(a1)
n1 := array1.Remove(1)
t.Assert(n1, 2)
v, ok := array1.Remove(1)
t.Assert(v, 2)
t.Assert(ok, true)
t.Assert(array1.Len(), 4)
n1 = array1.Remove(0)
t.Assert(n1, 1)
v, ok = array1.Remove(0)
t.Assert(v, 1)
t.Assert(ok, true)
t.Assert(array1.Len(), 3)
n1 = array1.Remove(2)
t.Assert(n1, 4)
v, ok = array1.Remove(2)
t.Assert(v, 4)
t.Assert(ok, true)
t.Assert(array1.Len(), 2)
})
}

View File

@ -29,13 +29,26 @@ func Test_StrArray_Basic(t *testing.T) {
t.Assert(array.Slice(), expect)
t.Assert(array.Interfaces(), expect)
array.Set(0, "100")
t.Assert(array.Get(0), 100)
t.Assert(array.Get(1), 1)
v, ok := array.Get(0)
t.Assert(v, 100)
t.Assert(ok, true)
t.Assert(array.Search("100"), 0)
t.Assert(array.Contains("100"), true)
t.Assert(array.Remove(0), 100)
t.Assert(array.Remove(-1), "")
t.Assert(array.Remove(100000), "")
v, ok = array.Remove(0)
t.Assert(v, 100)
t.Assert(ok, true)
v, ok = array.Remove(-1)
t.Assert(v, "")
t.Assert(ok, false)
v, ok = array.Remove(100000)
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.Contains("100"), false)
array.Append("4")
t.Assert(array.Len(), 4)
@ -79,10 +92,27 @@ func TestStrArray_PushAndPop(t *testing.T) {
expect := []string{"0", "1", "2", "3"}
array := garray.NewStrArrayFrom(expect)
t.Assert(array.Slice(), expect)
t.Assert(array.PopLeft(), "0")
t.Assert(array.PopRight(), "3")
t.AssertIN(array.PopRand(), []string{"1", "2"})
t.AssertIN(array.PopRand(), []string{"1", "2"})
v, ok := array.PopLeft()
t.Assert(v, "0")
t.Assert(ok, true)
v, ok = array.PopRight()
t.Assert(v, "3")
t.Assert(ok, true)
v, ok = array.PopRand()
t.AssertIN(v, []string{"1", "2"})
t.Assert(ok, true)
v, ok = array.PopRand()
t.AssertIN(v, []string{"1", "2"})
t.Assert(ok, true)
v, ok = array.PopRand()
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.Len(), 0)
array.PushLeft("1").PushRight("2")
t.Assert(array.Slice(), []string{"1", "2"})
@ -92,11 +122,19 @@ func TestStrArray_PushAndPop(t *testing.T) {
func TestStrArray_PopLeftsAndPopRights(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArray()
t.Assert(array.PopLeft(), nil)
v, ok := array.PopLeft()
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.PopLefts(10), nil)
t.Assert(array.PopRight(), nil)
v, ok = array.PopRight()
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.PopRights(10), nil)
t.Assert(array.PopRand(), nil)
v, ok = array.PopRand()
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.PopRands(10), nil)
})
@ -171,10 +209,12 @@ func TestStrArray_Fill(t *testing.T) {
a2 := []string{"0"}
array1 := garray.NewStrArrayFrom(a1)
array2 := garray.NewStrArrayFrom(a2)
t.Assert(array1.Fill(1, 2, "100").Slice(), []string{"0", "100", "100"})
t.Assert(array2.Fill(0, 2, "100").Slice(), []string{"100", "100"})
s1 := array2.Fill(-1, 2, "100")
t.Assert(s1.Len(), 2)
t.Assert(array1.Fill(1, 2, "100"), nil)
t.Assert(array1.Slice(), []string{"0", "100", "100"})
t.Assert(array2.Fill(0, 2, "100"), nil)
t.Assert(array2.Slice(), []string{"100", "100"})
t.AssertNE(array2.Fill(-1, 2, "100"), nil)
t.Assert(array2.Len(), 2)
})
}
@ -250,10 +290,11 @@ func TestStrArray_Rand(t *testing.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
t.Assert(len(array1.Rands(2)), "2")
t.Assert(len(array1.Rands(10)), "7")
t.Assert(len(array1.Rands(10)), 10)
t.AssertIN(array1.Rands(1)[0], a1)
t.Assert(len(array1.Rand()), 1)
t.AssertIN(array1.Rand(), a1)
v, ok := array1.Rand()
t.Assert(ok, true)
t.AssertIN(v, a1)
})
}
@ -373,9 +414,10 @@ func TestStrArray_PopRand(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
str1 := array1.PopRand()
str1, ok := array1.PopRand()
t.Assert(strings.Contains("0,1,2,3,4,5,6", str1), true)
t.Assert(array1.Len(), 6)
t.Assert(ok, true)
})
}
@ -405,11 +447,13 @@ func TestStrArray_Remove(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "a", "c"}
array1 := garray.NewStrArrayFrom(a1)
s1 := array1.Remove(1)
s1, ok := array1.Remove(1)
t.Assert(s1, "a")
t.Assert(ok, true)
t.Assert(array1.Len(), 4)
s1 = array1.Remove(3)
s1, ok = array1.Remove(3)
t.Assert(s1, "c")
t.Assert(ok, true)
t.Assert(array1.Len(), 3)
})
}

View File

@ -99,8 +99,13 @@ func TestSortedArray_Get(t *testing.T) {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
t.Assert(array1.Get(2), "f")
t.Assert(array1.Get(1), "c")
v, ok := array1.Get(2)
t.Assert(v, "f")
t.Assert(ok, true)
v, ok = array1.Get(1)
t.Assert(v, "c")
t.Assert(ok, true)
})
}
@ -112,20 +117,28 @@ func TestSortedArray_Remove(t *testing.T) {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.Remove(1)
i1, ok := array1.Remove(1)
t.Assert(ok, true)
t.Assert(gconv.String(i1), "b")
t.Assert(array1.Len(), 3)
t.Assert(array1.Contains("b"), false)
t.Assert(array1.Remove(-1), nil)
t.Assert(array1.Remove(100000), nil)
v, ok := array1.Remove(-1)
t.Assert(v, nil)
t.Assert(ok, false)
i2 := array1.Remove(0)
v, ok = array1.Remove(100000)
t.Assert(v, nil)
t.Assert(ok, false)
i2, ok := array1.Remove(0)
t.Assert(ok, true)
t.Assert(gconv.String(i2), "a")
t.Assert(array1.Len(), 2)
t.Assert(array1.Contains("a"), false)
i3 := array1.Remove(1)
i3, ok := array1.Remove(1)
t.Assert(ok, true)
t.Assert(gconv.String(i3), "d")
t.Assert(array1.Len(), 1)
t.Assert(array1.Contains("d"), false)
@ -140,7 +153,8 @@ func TestSortedArray_PopLeft(t *testing.T) {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.PopLeft()
i1, ok := array1.PopLeft()
t.Assert(ok, true)
t.Assert(gconv.String(i1), "a")
t.Assert(array1.Len(), 3)
t.Assert(array1, []interface{}{"b", "c", "d"})
@ -155,7 +169,8 @@ func TestSortedArray_PopRight(t *testing.T) {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.PopRight()
i1, ok := array1.PopRight()
t.Assert(ok, true)
t.Assert(gconv.String(i1), "d")
t.Assert(array1.Len(), 3)
t.Assert(array1, []interface{}{"a", "b", "c"})
@ -170,7 +185,8 @@ func TestSortedArray_PopRand(t *testing.T) {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.PopRand()
i1, ok := array1.PopRand()
t.Assert(ok, true)
t.AssertIN(i1, []interface{}{"a", "d", "c", "b"})
t.Assert(array1.Len(), 3)
@ -200,11 +216,19 @@ func TestSortedArray_PopRands(t *testing.T) {
func TestSortedArray_Empty(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedArray(gutil.ComparatorInt)
t.Assert(array.PopLeft(), nil)
v, ok := array.PopLeft()
t.Assert(v, nil)
t.Assert(ok, false)
t.Assert(array.PopLefts(10), nil)
t.Assert(array.PopRight(), nil)
v, ok = array.PopRight()
t.Assert(v, nil)
t.Assert(ok, false)
t.Assert(array.PopRights(10), nil)
t.Assert(array.PopRand(), nil)
v, ok = array.PopRand()
t.Assert(v, nil)
t.Assert(ok, false)
t.Assert(array.PopRands(10), nil)
})
}
@ -406,7 +430,8 @@ func TestSortedArray_Rand(t *testing.T) {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.Rand()
i1, ok := array1.Rand()
t.Assert(ok, true)
t.AssertIN(i1, []interface{}{"a", "d", "c"})
t.Assert(array1.Len(), 3)
})
@ -426,7 +451,7 @@ func TestSortedArray_Rands(t *testing.T) {
t.Assert(array1.Len(), 3)
i1 = array1.Rands(4)
t.Assert(len(i1), 3)
t.Assert(len(i1), 4)
})
}
@ -625,9 +650,22 @@ func TestSortedArray_Json(t *testing.T) {
t.Assert(user.Name, data["Name"])
t.AssertNE(user.Scores, nil)
t.Assert(user.Scores.Len(), 3)
t.AssertIN(user.Scores.PopLeft(), data["Scores"])
t.AssertIN(user.Scores.PopLeft(), data["Scores"])
t.AssertIN(user.Scores.PopLeft(), data["Scores"])
v, ok := user.Scores.PopLeft()
t.AssertIN(v, data["Scores"])
t.Assert(ok, true)
v, ok = user.Scores.PopLeft()
t.AssertIN(v, data["Scores"])
t.Assert(ok, true)
v, ok = user.Scores.PopLeft()
t.AssertIN(v, data["Scores"])
t.Assert(ok, true)
v, ok = user.Scores.PopLeft()
t.Assert(v, nil)
t.Assert(ok, false)
})
}

View File

@ -68,9 +68,17 @@ func TestSortedIntArray_Get(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5, 0}
array1 := garray.NewSortedIntArrayFrom(a1)
t.Assert(array1.Get(0), 0)
t.Assert(array1.Get(1), 1)
t.Assert(array1.Get(3), 5)
v, ok := array1.Get(0)
t.Assert(v, 0)
t.Assert(ok, true)
v, ok = array1.Get(1)
t.Assert(v, 1)
t.Assert(ok, true)
v, ok = array1.Get(3)
t.Assert(v, 5)
t.Assert(ok, true)
})
}
@ -79,26 +87,39 @@ func TestSortedIntArray_Remove(t *testing.T) {
a1 := []int{1, 3, 5, 0}
array1 := garray.NewSortedIntArrayFrom(a1)
t.Assert(array1.Remove(-1), 0)
t.Assert(array1.Remove(100000), 0)
v, ok := array1.Remove(-1)
t.Assert(v, 0)
t.Assert(ok, false)
v, ok = array1.Remove(-100000)
t.Assert(v, 0)
t.Assert(ok, false)
v, ok = array1.Remove(2)
t.Assert(v, 3)
t.Assert(ok, true)
i1 := array1.Remove(2)
t.Assert(i1, 3)
t.Assert(array1.Search(5), 2)
// 再次删除剩下的数组中的第一个
i2 := array1.Remove(0)
t.Assert(i2, 0)
v, ok = array1.Remove(0)
t.Assert(v, 0)
t.Assert(ok, true)
t.Assert(array1.Search(5), 1)
a2 := []int{1, 3, 4}
array2 := garray.NewSortedIntArrayFrom(a2)
i3 := array2.Remove(1)
v, ok = array2.Remove(1)
t.Assert(v, 3)
t.Assert(ok, true)
t.Assert(array2.Search(1), 0)
t.Assert(i3, 3)
i3 = array2.Remove(1)
v, ok = array2.Remove(1)
t.Assert(v, 4)
t.Assert(ok, true)
t.Assert(array2.Search(4), -1)
t.Assert(i3, 4)
})
}
@ -106,8 +127,9 @@ func TestSortedIntArray_PopLeft(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5, 2}
array1 := garray.NewSortedIntArrayFrom(a1)
i1 := array1.PopLeft()
t.Assert(i1, 1)
v, ok := array1.PopLeft()
t.Assert(v, 1)
t.Assert(ok, true)
t.Assert(array1.Len(), 3)
t.Assert(array1.Search(1), -1)
})
@ -117,8 +139,9 @@ func TestSortedIntArray_PopRight(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5, 2}
array1 := garray.NewSortedIntArrayFrom(a1)
i1 := array1.PopRight()
t.Assert(i1, 5)
v, ok := array1.PopRight()
t.Assert(v, 5)
t.Assert(ok, true)
t.Assert(array1.Len(), 3)
t.Assert(array1.Search(5), -1)
})
@ -128,7 +151,8 @@ func TestSortedIntArray_PopRand(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5, 2}
array1 := garray.NewSortedIntArrayFrom(a1)
i1 := array1.PopRand()
i1, ok := array1.PopRand()
t.Assert(ok, true)
t.Assert(array1.Len(), 3)
t.Assert(array1.Search(i1), -1)
t.AssertIN(i1, []int{1, 3, 5, 2})
@ -155,11 +179,19 @@ func TestSortedIntArray_PopRands(t *testing.T) {
func TestSortedIntArray_Empty(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedIntArray()
t.Assert(array.PopLeft(), 0)
v, ok := array.PopLeft()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.PopLefts(10), nil)
t.Assert(array.PopRight(), 0)
v, ok = array.PopRight()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.PopRights(10), nil)
t.Assert(array.PopRand(), 0)
v, ok = array.PopRand()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.PopRands(10), nil)
})
}
@ -340,8 +372,9 @@ func TestSortedIntArray_Rand(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
ns1 := array1.Rand() //按每几个元素切成一个数组
ns1, ok := array1.Rand()
t.AssertIN(ns1, a1)
t.Assert(ok, true)
})
}
@ -349,13 +382,12 @@ func TestSortedIntArray_Rands(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
ns1 := array1.Rands(2) //按每几个元素切成一个数组
ns1 := array1.Rands(2)
t.AssertIN(ns1, a1)
t.Assert(len(ns1), 2)
ns2 := array1.Rands(6) //按每几个元素切成一个数组
t.AssertIN(ns2, a1)
t.Assert(len(ns2), 5)
ns2 := array1.Rands(6)
t.Assert(len(ns2), 6)
})
}

View File

@ -68,8 +68,13 @@ func TestSortedStrArray_Get(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
t.Assert(array1.Get(2), "c")
t.Assert(array1.Get(0), "a")
v, ok := array1.Get(2)
t.Assert(v, "c")
t.Assert(ok, true)
v, ok = array1.Get(0)
t.Assert(v, "a")
t.Assert(ok, true)
})
}
@ -78,20 +83,36 @@ func TestSortedStrArray_Remove(t *testing.T) {
a1 := []string{"a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
t.Assert(array1.Remove(-1), "")
t.Assert(array1.Remove(100000), "")
v, ok := array1.Remove(-1)
t.Assert(v, "")
t.Assert(ok, false)
v, ok = array1.Remove(100000)
t.Assert(v, "")
t.Assert(ok, false)
v, ok = array1.Remove(2)
t.Assert(v, "c")
t.Assert(ok, true)
v, ok = array1.Get(2)
t.Assert(v, "d")
t.Assert(ok, true)
t.Assert(array1.Remove(2), "c")
t.Assert(array1.Get(2), "d")
t.Assert(array1.Len(), 3)
t.Assert(array1.Contains("c"), false)
t.Assert(array1.Remove(0), "a")
v, ok = array1.Remove(0)
t.Assert(v, "a")
t.Assert(ok, true)
t.Assert(array1.Len(), 2)
t.Assert(array1.Contains("a"), false)
// 此时array1里的元素只剩下2个
t.Assert(array1.Remove(1), "d")
v, ok = array1.Remove(1)
t.Assert(v, "d")
t.Assert(ok, true)
t.Assert(array1.Len(), 1)
})
}
@ -100,8 +121,9 @@ func TestSortedStrArray_PopLeft(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
s1 := array1.PopLeft()
t.Assert(s1, "a")
v, ok := array1.PopLeft()
t.Assert(v, "a")
t.Assert(ok, true)
t.Assert(array1.Len(), 4)
t.Assert(array1.Contains("a"), false)
})
@ -111,8 +133,9 @@ func TestSortedStrArray_PopRight(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
s1 := array1.PopRight()
t.Assert(s1, "e")
v, ok := array1.PopRight()
t.Assert(v, "e")
t.Assert(ok, ok)
t.Assert(array1.Len(), 4)
t.Assert(array1.Contains("e"), false)
})
@ -122,7 +145,8 @@ func TestSortedStrArray_PopRand(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
s1 := array1.PopRand()
s1, ok := array1.PopRand()
t.Assert(ok, true)
t.AssertIN(s1, []string{"e", "a", "d", "c", "b"})
t.Assert(array1.Len(), 4)
t.Assert(array1.Contains(s1), false)
@ -147,11 +171,19 @@ func TestSortedStrArray_PopRands(t *testing.T) {
func TestSortedStrArray_Empty(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedStrArray()
t.Assert(array.PopLeft(), nil)
v, ok := array.PopLeft()
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.PopLefts(10), nil)
t.Assert(array.PopRight(), nil)
v, ok = array.PopRight()
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.PopRights(10), nil)
t.Assert(array.PopRand(), nil)
v, ok = array.PopRand()
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.PopRands(10), nil)
})
}
@ -283,7 +315,9 @@ func TestSortedStrArray_Rand(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d"}
array1 := garray.NewSortedStrArrayFrom(a1)
t.AssertIN(array1.Rand(), []string{"e", "a", "d"})
v, ok := array1.Rand()
t.AssertIN(v, []string{"e", "a", "d"})
t.Assert(ok, true)
})
}
@ -297,8 +331,7 @@ func TestSortedStrArray_Rands(t *testing.T) {
t.Assert(len(s1), 2)
s1 = array1.Rands(4)
t.AssertIN(s1, []string{"e", "a", "d"})
t.Assert(len(s1), 3)
t.Assert(len(s1), 4)
})
}

View File

@ -187,9 +187,9 @@ func (l *Logger) rotateChecksTimely() {
for _, array := range backupFilesMap {
diff := array.Len() - l.config.RotateBackupLimit
for i := 0; i < diff; i++ {
path := array.PopLeft().(string)
path, _ := array.PopLeft()
intlog.Printf(`remove exceeded backup limit file: %s`, path)
if err := gfile.Remove(path); err != nil {
if err := gfile.Remove(path.(string)); err != nil {
intlog.Print(err)
}
}

View File

@ -11,7 +11,8 @@
// between gtimer and gcron are as follows:
// 1. package gcron is implemented based on package gtimer.
// 2. gtimer is designed for high performance and for millions of timing jobs.
// 3. gcron supports configuration pattern grammar like linux crontab, which is more manually readable.
// 3. gcron supports configuration pattern grammar like linux crontab, which is more manually
// readable.
// 4. gtimer's benchmark OP is measured in nanoseconds, and gcron's benchmark OP is measured
// in microseconds.
//

View File

@ -105,6 +105,7 @@ func Symbols(n int) string {
}
// Perm returns, as a slice of n int numbers, a pseudo-random permutation of the integers [0,n).
// TODO performance improving for large slice producing.
func Perm(n int) []int {
m := make([]int, n)
for i := 0; i < n; i++ {

View File

@ -18,13 +18,31 @@ import (
var buffer = make([]byte, 8)
func Benchmark_Rand1(b *testing.B) {
func Benchmark_Rand_Intn(b *testing.B) {
for i := 0; i < b.N; i++ {
grand.N(0, 99)
}
}
func Benchmark_Rand2(b *testing.B) {
func Benchmark_Perm10(b *testing.B) {
for i := 0; i < b.N; i++ {
grand.Perm(10)
}
}
func Benchmark_Perm100(b *testing.B) {
for i := 0; i < b.N; i++ {
grand.Perm(100)
}
}
func Benchmark_Rand_N1(b *testing.B) {
for i := 0; i < b.N; i++ {
grand.N(0, 99)
}
}
func Benchmark_Rand_N2(b *testing.B) {
for i := 0; i < b.N; i++ {
grand.N(0, 999999999)
}