From d780cf64c2480a22f1f1dad537537d0b805d12f0 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 20 Feb 2019 14:18:11 +0800 Subject: [PATCH] garray updates --- TODO.MD | 2 +- g/container/garray/garray_normal_int.go | 27 ++++-- g/container/garray/garray_normal_interface.go | 47 +++++++--- g/container/garray/garray_normal_string.go | 26 ++++-- g/container/garray/garray_sorted_int.go | 27 ++++-- g/container/garray/garray_sorted_interface.go | 27 ++++-- g/container/garray/garray_sorted_string.go | 26 ++++-- g/container/garray/garray_z_example_test.go | 87 +++++++++++++++++++ 8 files changed, 220 insertions(+), 49 deletions(-) create mode 100644 g/container/garray/garray_z_example_test.go diff --git a/TODO.MD b/TODO.MD index 788d4e478..3f7032442 100644 --- a/TODO.MD +++ b/TODO.MD @@ -52,7 +52,7 @@ 1. 从ghttp中剥离SESSION功能构成单独的模块gsession; 1. 改进gproc进程间通信处理逻辑,提高稳定性,以应对进程间大批量的数据发送/接收; 1. gdb的Data方法支持struct参数传入; - +1. ghttp的热重启的本地进程端口监听,在不使用该特性时默认关闭掉; diff --git a/g/container/garray/garray_normal_int.go b/g/container/garray/garray_normal_int.go index 3b5451140..a95da3308 100644 --- a/g/container/garray/garray_normal_int.go +++ b/g/container/garray/garray_normal_int.go @@ -7,12 +7,12 @@ package garray import ( + "bytes" "github.com/gogf/gf/g/internal/rwmutex" "github.com/gogf/gf/g/util/gconv" "github.com/gogf/gf/g/util/grand" "math" "sort" - "strings" ) type IntArray struct { @@ -425,17 +425,21 @@ func (a *IntArray) RLockFunc(f func(array []int)) *IntArray { return a } -// Merge two arrays. +// Merge two arrays. The parameter can be *IntArray or any slice type. // // 合并两个数组. -func (a *IntArray) Merge(array *IntArray) *IntArray { +func (a *IntArray) Merge(array interface{}) *IntArray { a.mu.Lock() defer a.mu.Unlock() - if a != array { - array.mu.RLock() - defer array.mu.RUnlock() + if other, ok := array.(*IntArray); ok { + if a != array { + other.mu.RLock() + defer other.mu.RUnlock() + } + a.array = append(a.array, other.array...) + } else { + a.array = append(a.array, gconv.Ints(array)...) } - a.array = append(a.array, array.array...) return a } @@ -588,5 +592,12 @@ func (a *IntArray) Reverse() *IntArray { func (a *IntArray) Join(glue string) string { a.mu.RLock() defer a.mu.RUnlock() - return strings.Join(gconv.Strings(a.array), glue) + buffer := bytes.NewBuffer(nil) + for k, v := range a.array { + buffer.WriteString(gconv.String(v)) + if k != len(a.array) - 1 { + buffer.WriteString(glue) + } + } + return buffer.String() } \ No newline at end of file diff --git a/g/container/garray/garray_normal_interface.go b/g/container/garray/garray_normal_interface.go index 2894d495b..5de4f2ed9 100644 --- a/g/container/garray/garray_normal_interface.go +++ b/g/container/garray/garray_normal_interface.go @@ -7,12 +7,12 @@ package garray import ( + "bytes" "github.com/gogf/gf/g/internal/rwmutex" "github.com/gogf/gf/g/util/gconv" "github.com/gogf/gf/g/util/grand" "math" "sort" - "strings" ) type Array struct { @@ -30,8 +30,6 @@ func New(unsafe...bool) *Array { } // See New. -// -// 同New方法。 func NewArray(unsafe...bool) *Array { return NewArraySize(0, 0, unsafe...) } @@ -48,6 +46,11 @@ func NewArraySize(size int, cap int, unsafe...bool) *Array { } } +// See NewArrayFrom. +func NewFrom(array []interface{}, unsafe...bool) *Array { + return NewArrayFrom(array, unsafe...) +} + // Create an array with given slice . // The param used to specify whether using array with un-concurrent-safety, // which is false in default, means concurrent-safe in default. @@ -408,17 +411,21 @@ func (a *Array) RLockFunc(f func(array []interface{})) *Array { return a } -// Merge two arrays. +// Merge two arrays. The parameter can be *Array or any slice type. // // 合并两个数组. -func (a *Array) Merge(array *Array) *Array { +func (a *Array) Merge(array interface{}) *Array { a.mu.Lock() defer a.mu.Unlock() - if a != array { - array.mu.RLock() - defer array.mu.RUnlock() + if other, ok := array.(*Array); ok { + if a != array { + other.mu.RLock() + defer other.mu.RUnlock() + } + a.array = append(a.array, other.array...) + } else { + a.array = append(a.array, gconv.Interfaces(array)...) } - a.array = append(a.array, array.array...) return a } @@ -570,7 +577,14 @@ func (a *Array) Reverse() *Array { func (a *Array) Join(glue string) string { a.mu.RLock() defer a.mu.RUnlock() - return strings.Join(gconv.Strings(a.array), glue) + buffer := bytes.NewBuffer(nil) + for k, v := range a.array { + buffer.WriteString(gconv.String(v)) + if k != len(a.array) - 1 { + buffer.WriteString(glue) + } + } + return buffer.String() } // Counts all the values of an array. @@ -584,4 +598,17 @@ func (a *Array) CountValues() map[interface{}]int { m[v]++ } return m +} + +// String returns current array as a string. +// +// 将当前数组转换为字符串返回。 +func (a *Array) String() string { + a.mu.RLock() + defer a.mu.RUnlock() + buffer := bytes.NewBuffer(nil) + for _, v := range a.array { + buffer.WriteString(gconv.String(v)) + } + return buffer.String() } \ No newline at end of file diff --git a/g/container/garray/garray_normal_string.go b/g/container/garray/garray_normal_string.go index b915d2c56..3cef15759 100644 --- a/g/container/garray/garray_normal_string.go +++ b/g/container/garray/garray_normal_string.go @@ -7,6 +7,7 @@ package garray import ( + "bytes" "github.com/gogf/gf/g/internal/rwmutex" "github.com/gogf/gf/g/util/gconv" "github.com/gogf/gf/g/util/grand" @@ -423,17 +424,21 @@ func (a *StringArray) RLockFunc(f func(array []string)) *StringArray { return a } -// Merge two arrays. +// Merge two arrays. The parameter can be *StringArray or any slice type. // // 合并两个数组. -func (a *StringArray) Merge(array *StringArray) *StringArray { +func (a *StringArray) Merge(array interface{}) *StringArray { a.mu.Lock() defer a.mu.Unlock() - if a != array { - array.mu.RLock() - defer array.mu.RUnlock() + if other, ok := array.(*StringArray); ok { + if a != array { + other.mu.RLock() + defer other.mu.RUnlock() + } + a.array = append(a.array, other.array...) + } else { + a.array = append(a.array, gconv.Strings(array)...) } - a.array = append(a.array, array.array...) return a } @@ -587,6 +592,13 @@ func (a *StringArray) Reverse() *StringArray { func (a *StringArray) Join(glue string) string { a.mu.RLock() defer a.mu.RUnlock() - return strings.Join(a.array, glue) + buffer := bytes.NewBuffer(nil) + for k, v := range a.array { + buffer.WriteString(gconv.String(v)) + if k != len(a.array) - 1 { + buffer.WriteString(glue) + } + } + return buffer.String() } diff --git a/g/container/garray/garray_sorted_int.go b/g/container/garray/garray_sorted_int.go index d4f962459..ea6c1bbe7 100644 --- a/g/container/garray/garray_sorted_int.go +++ b/g/container/garray/garray_sorted_int.go @@ -7,13 +7,13 @@ package garray import ( + "bytes" "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" "math" "sort" - "strings" ) // 默认按照从小到大进行排序 @@ -399,17 +399,21 @@ func (a *SortedIntArray) RLockFunc(f func(array []int)) *SortedIntArray { return a } -// Merge two arrays. +// Merge two arrays. The parameter can be *SortedIntArray or any slice type. // // 合并两个数组. -func (a *SortedIntArray) Merge(array *SortedIntArray) *SortedIntArray { +func (a *SortedIntArray) Merge(array interface{}) *SortedIntArray { a.mu.Lock() defer a.mu.Unlock() - if a != array { - array.mu.RLock() - defer array.mu.RUnlock() + if other, ok := array.(*SortedIntArray); ok { + if a != array { + other.mu.RLock() + defer other.mu.RUnlock() + } + a.array = append(a.array, other.array...) + } else { + a.array = append(a.array, gconv.Ints(array)...) } - a.array = append(a.array, array.array...) sort.Ints(a.array) return a } @@ -488,5 +492,12 @@ func (a *SortedIntArray) Rand(size int) []int { func (a *SortedIntArray) Join(glue string) string { a.mu.RLock() defer a.mu.RUnlock() - return strings.Join(gconv.Strings(a.array), glue) + buffer := bytes.NewBuffer(nil) + for k, v := range a.array { + buffer.WriteString(gconv.String(v)) + if k != len(a.array) - 1 { + buffer.WriteString(glue) + } + } + return buffer.String() } \ No newline at end of file diff --git a/g/container/garray/garray_sorted_interface.go b/g/container/garray/garray_sorted_interface.go index ee5830c68..faf3921f0 100644 --- a/g/container/garray/garray_sorted_interface.go +++ b/g/container/garray/garray_sorted_interface.go @@ -7,13 +7,13 @@ package garray import ( + "bytes" "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" "math" "sort" - "strings" ) // 默认按照从小到大进行排序 @@ -406,17 +406,21 @@ func (a *SortedArray) RLockFunc(f func(array []interface{})) *SortedArray { return a } -// Merge two arrays. +// Merge two arrays. The parameter can be *SortedArray or any slice type. // // 合并两个数组. -func (a *SortedArray) Merge(array *SortedArray) *SortedArray { +func (a *SortedArray) Merge(array interface{}) *SortedArray { a.mu.Lock() defer a.mu.Unlock() - if a != array { - array.mu.RLock() - defer array.mu.RUnlock() + if other, ok := array.(*SortedArray); ok { + if a != array { + other.mu.RLock() + defer other.mu.RUnlock() + } + a.array = append(a.array, other.array...) + } else { + a.array = append(a.array, gconv.Interfaces(array)...) } - a.array = append(a.array, array.array...) sort.Slice(a.array, func(i, j int) bool { return a.compareFunc(a.array[i], a.array[j]) < 0 }) @@ -497,5 +501,12 @@ func (a *SortedArray) Rand(size int) []interface{} { func (a *SortedArray) Join(glue string) string { a.mu.RLock() defer a.mu.RUnlock() - return strings.Join(gconv.Strings(a.array), glue) + buffer := bytes.NewBuffer(nil) + for k, v := range a.array { + buffer.WriteString(gconv.String(v)) + if k != len(a.array) - 1 { + buffer.WriteString(glue) + } + } + return buffer.String() } \ No newline at end of file diff --git a/g/container/garray/garray_sorted_string.go b/g/container/garray/garray_sorted_string.go index 00f9e3a61..1a95e37b5 100644 --- a/g/container/garray/garray_sorted_string.go +++ b/g/container/garray/garray_sorted_string.go @@ -7,6 +7,7 @@ package garray import ( + "bytes" "github.com/gogf/gf/g/container/gtype" "github.com/gogf/gf/g/internal/rwmutex" "github.com/gogf/gf/g/util/gconv" @@ -393,17 +394,21 @@ func (a *SortedStringArray) RLockFunc(f func(array []string)) *SortedStringArray return a } -// Merge two arrays. +// Merge two arrays. The parameter can be *SortedStringArray or any slice type. // // 合并两个数组. -func (a *SortedStringArray) Merge(array *SortedStringArray) *SortedStringArray { +func (a *SortedStringArray) Merge(array interface{}) *SortedStringArray { a.mu.Lock() defer a.mu.Unlock() - if a != array { - array.mu.RLock() - defer array.mu.RUnlock() + if other, ok := array.(*SortedStringArray); ok { + if a != array { + other.mu.RLock() + defer other.mu.RUnlock() + } + a.array = append(a.array, other.array...) + } else { + a.array = append(a.array, gconv.Strings(array)...) } - a.array = append(a.array, array.array...) sort.Strings(a.array) return a } @@ -482,5 +487,12 @@ func (a *SortedStringArray) Rand(size int) []string { func (a *SortedStringArray) Join(glue string) string { a.mu.RLock() defer a.mu.RUnlock() - return strings.Join(a.array, glue) + buffer := bytes.NewBuffer(nil) + for k, v := range a.array { + buffer.WriteString(gconv.String(v)) + if k != len(a.array) - 1 { + buffer.WriteString(glue) + } + } + return buffer.String() } \ No newline at end of file diff --git a/g/container/garray/garray_z_example_test.go b/g/container/garray/garray_z_example_test.go new file mode 100644 index 000000000..af02b8de9 --- /dev/null +++ b/g/container/garray/garray_z_example_test.go @@ -0,0 +1,87 @@ +// Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package garray_test + +import ( + "fmt" + "github.com/gogf/gf/g/container/garray" +) + +func Example_basic() { + // 创建普通的数组,默认并发安全(带锁) + a := garray.New() + + // 添加数据项 + for i := 0; i < 10; i++ { + a.Append(i) + } + + // 获取当前数组长度 + fmt.Println(a.Len()) + + // 获取当前数据项列表 + fmt.Println(a.Slice()) + + // 获取指定索引项 + fmt.Println(a.Get(6)) + + // 查找指定数据项是否存在 + fmt.Println(a.Contains(6)) + fmt.Println(a.Contains(100)) + + // 在指定索引前插入数据项 + a.InsertAfter(9, 11) + // 在指定索引后插入数据项 + a.InsertBefore(10, 10) + + fmt.Println(a.Slice()) + + // 修改指定索引的数据项 + a.Set(0, 100) + fmt.Println(a.Slice()) + + // 搜索数据项,返回搜索到的索引位置 + fmt.Println(a.Search(5)) + + // 删除指定索引的数据项 + a.Remove(0) + fmt.Println(a.Slice()) + + // 清空数组 + fmt.Println(a.Slice()) + a.Clear() + fmt.Println(a.Slice()) + + // Output: + // 10 + // [0 1 2 3 4 5 6 7 8 9] + // 6 + // true + // false + // [0 1 2 3 4 5 6 7 8 9 10 11] + // [100 1 2 3 4 5 6 7 8 9 10 11] + // 5 + // [1 2 3 4 5 6 7 8 9 10 11] + // [1 2 3 4 5 6 7 8 9 10 11] + // [] +} + +func Example_merge() { + array1 := garray.NewFrom([]interface{}{1,2}) + array2 := garray.NewFrom([]interface{}{3,4}) + slice1 := []interface{}{5,6} + slice2 := []int{7,8} + fmt.Println(array1.Slice()) + array1.Merge(array2) + array1.Merge(slice1) + array1.Merge(slice2) + fmt.Println(array1.Slice()) + + // Output: + // [1 2] + // [1 2 3 4 5 6 7 8] +} \ No newline at end of file