mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
Merge branch 'gogf:master' into master
This commit is contained in:
709
container/garray/garray_z_example_int_test.go
Normal file
709
container/garray/garray_z_example_int_test.go
Normal file
@ -0,0 +1,709 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). 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/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
func ExampleIntArray_Walk() {
|
||||
var array garray.IntArray
|
||||
tables := g.SliceInt{10, 20}
|
||||
prefix := 99
|
||||
array.Append(tables...)
|
||||
// Add prefix for given table names.
|
||||
array.Walk(func(value int) int {
|
||||
return prefix + value
|
||||
})
|
||||
fmt.Println(array.Slice())
|
||||
|
||||
// Output:
|
||||
// [109 119]
|
||||
}
|
||||
|
||||
func ExampleNewIntArray() {
|
||||
s := garray.NewIntArray()
|
||||
s.Append(10)
|
||||
s.Append(20)
|
||||
s.Append(15)
|
||||
s.Append(30)
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10 20 15 30]
|
||||
}
|
||||
|
||||
func ExampleNewIntArraySize() {
|
||||
s := garray.NewIntArraySize(3, 5)
|
||||
s.Set(0, 10)
|
||||
s.Set(1, 20)
|
||||
s.Set(2, 15)
|
||||
s.Set(3, 30)
|
||||
fmt.Println(s.Slice(), s.Len(), cap(s.Slice()))
|
||||
|
||||
// Output:
|
||||
// [10 20 15] 3 5
|
||||
}
|
||||
|
||||
func ExampleNewIntArrayFrom() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30})
|
||||
fmt.Println(s.Slice(), s.Len(), cap(s.Slice()))
|
||||
|
||||
// Output:
|
||||
// [10 20 15 30] 4 4
|
||||
}
|
||||
|
||||
func ExampleNewIntArrayFromCopy() {
|
||||
s := garray.NewIntArrayFromCopy(g.SliceInt{10, 20, 15, 30})
|
||||
fmt.Println(s.Slice(), s.Len(), cap(s.Slice()))
|
||||
|
||||
// Output:
|
||||
// [10 20 15 30] 4 4
|
||||
}
|
||||
|
||||
func ExampleIntArray_At() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30})
|
||||
sAt := s.At(2)
|
||||
fmt.Println(sAt)
|
||||
|
||||
// Output:
|
||||
// 15
|
||||
}
|
||||
|
||||
func ExampleIntArray_Get() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30})
|
||||
sGet, sBool := s.Get(3)
|
||||
fmt.Println(sGet, sBool)
|
||||
|
||||
// Output:
|
||||
// 30 true
|
||||
}
|
||||
|
||||
func ExampleIntArray_Set() {
|
||||
s := garray.NewIntArraySize(3, 5)
|
||||
s.Set(0, 10)
|
||||
s.Set(1, 20)
|
||||
s.Set(2, 15)
|
||||
s.Set(3, 30)
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10 20 15]
|
||||
}
|
||||
|
||||
func ExampleIntArray_SetArray() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30})
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10 20 15 30]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Replace() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30})
|
||||
fmt.Println(s.Slice())
|
||||
s.Replace(g.SliceInt{12, 13})
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10 20 15 30]
|
||||
// [12 13 15 30]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Sum() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30})
|
||||
a := s.Sum()
|
||||
fmt.Println(a)
|
||||
|
||||
// Output:
|
||||
// 75
|
||||
}
|
||||
|
||||
func ExampleIntArray_Sort() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30})
|
||||
a := s.Sort()
|
||||
fmt.Println(a)
|
||||
|
||||
// Output:
|
||||
// [10,15,20,30]
|
||||
}
|
||||
|
||||
func ExampleIntArray_SortFunc() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30})
|
||||
fmt.Println(s)
|
||||
s.SortFunc(func(v1, v2 int) bool {
|
||||
//fmt.Println(v1,v2)
|
||||
return v1 > v2
|
||||
})
|
||||
fmt.Println(s)
|
||||
s.SortFunc(func(v1, v2 int) bool {
|
||||
return v1 < v2
|
||||
})
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30]
|
||||
// [30,20,15,10]
|
||||
// [10,15,20,30]
|
||||
}
|
||||
|
||||
func ExampleIntArray_InsertBefore() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30})
|
||||
s.InsertBefore(1, 99)
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10 99 20 15 30]
|
||||
}
|
||||
|
||||
func ExampleIntArray_InsertAfter() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30})
|
||||
s.InsertAfter(1, 99)
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10 20 99 15 30]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Remove() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30})
|
||||
fmt.Println(s)
|
||||
s.Remove(1)
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30]
|
||||
// [10 15 30]
|
||||
}
|
||||
|
||||
func ExampleIntArray_RemoveValue() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30})
|
||||
fmt.Println(s)
|
||||
s.RemoveValue(20)
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30]
|
||||
// [10 15 30]
|
||||
}
|
||||
|
||||
func ExampleIntArray_PushLeft() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30})
|
||||
fmt.Println(s)
|
||||
s.PushLeft(96, 97, 98, 99)
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30]
|
||||
// [96 97 98 99 10 20 15 30]
|
||||
}
|
||||
|
||||
func ExampleIntArray_PushRight() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30})
|
||||
fmt.Println(s)
|
||||
s.PushRight(96, 97, 98, 99)
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30]
|
||||
// [10 20 15 30 96 97 98 99]
|
||||
}
|
||||
|
||||
func ExampleIntArray_PopLeft() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30})
|
||||
fmt.Println(s)
|
||||
s.PopLeft()
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30]
|
||||
// [20 15 30]
|
||||
}
|
||||
|
||||
func ExampleIntArray_PopRight() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30})
|
||||
fmt.Println(s)
|
||||
s.PopRight()
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30]
|
||||
// [10 20 15]
|
||||
}
|
||||
|
||||
func ExampleIntArray_PopRand() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60, 70})
|
||||
fmt.Println(s)
|
||||
r, _ := s.PopRand()
|
||||
fmt.Println(s)
|
||||
fmt.Println(r)
|
||||
|
||||
// May Output:
|
||||
// [10,20,15,30,40,50,60,70]
|
||||
// [10,20,15,30,40,60,70]
|
||||
// 50
|
||||
}
|
||||
|
||||
func ExampleIntArray_PopRands() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
r := s.PopRands(2)
|
||||
fmt.Println(s)
|
||||
fmt.Println(r)
|
||||
|
||||
// May Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [10,20,15,30,40]
|
||||
// [50 60]
|
||||
}
|
||||
|
||||
func ExampleIntArray_PopLefts() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
r := s.PopLefts(2)
|
||||
fmt.Println(s)
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [15,30,40,50,60]
|
||||
// [10 20]
|
||||
}
|
||||
|
||||
func ExampleIntArray_PopRights() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
r := s.PopRights(2)
|
||||
fmt.Println(s)
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [10,20,15,30,40]
|
||||
// [50 60]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Range() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
r := s.Range(2, 5)
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [15 30 40]
|
||||
}
|
||||
|
||||
func ExampleIntArray_SubSlice() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
r := s.SubSlice(3, 4)
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [30 40 50 60]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Append() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
s.Append(96, 97, 98)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [10,20,15,30,40,50,60,96,97,98]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Len() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Len())
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// 7
|
||||
}
|
||||
|
||||
func ExampleIntArray_Slice() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [10 20 15 30 40 50 60]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Interfaces() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
r := s.Interfaces()
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [10 20 15 30 40 50 60]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Clone() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
r := s.Clone()
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [10,20,15,30,40,50,60]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Clear() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Clear())
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// []
|
||||
// []
|
||||
}
|
||||
|
||||
func ExampleIntArray_Contains() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s.Contains(20))
|
||||
fmt.Println(s.Contains(21))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleIntArray_Search() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s.Search(20))
|
||||
fmt.Println(s.Search(21))
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// -1
|
||||
}
|
||||
|
||||
func ExampleIntArray_Unique() {
|
||||
s := garray.NewIntArray()
|
||||
s.SetArray(g.SliceInt{10, 20, 15, 15, 20, 50, 60})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Unique())
|
||||
|
||||
// Output:
|
||||
// [10,20,15,15,20,50,60]
|
||||
// [10,20,15,50,60]
|
||||
}
|
||||
|
||||
func ExampleIntArray_LockFunc() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
s.LockFunc(func(array []int) {
|
||||
for i := 0; i < len(array)-1; i++ {
|
||||
fmt.Println(array[i])
|
||||
}
|
||||
})
|
||||
|
||||
// Output:
|
||||
// 10
|
||||
// 20
|
||||
// 15
|
||||
// 30
|
||||
// 40
|
||||
// 50
|
||||
}
|
||||
|
||||
func ExampleIntArray_RLockFunc() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
s.RLockFunc(func(array []int) {
|
||||
for i := 0; i < len(array); i++ {
|
||||
fmt.Println(array[i])
|
||||
}
|
||||
})
|
||||
|
||||
// Output:
|
||||
// 10
|
||||
// 20
|
||||
// 15
|
||||
// 30
|
||||
// 40
|
||||
// 50
|
||||
// 60
|
||||
}
|
||||
|
||||
func ExampleIntArray_Merge() {
|
||||
s1 := garray.NewIntArray()
|
||||
s2 := garray.NewIntArray()
|
||||
s1.SetArray(g.SliceInt{10, 20, 15})
|
||||
s2.SetArray(g.SliceInt{40, 50, 60})
|
||||
fmt.Println(s1)
|
||||
fmt.Println(s2)
|
||||
s1.Merge(s2)
|
||||
fmt.Println(s1)
|
||||
|
||||
// Output:
|
||||
// [10,20,15]
|
||||
// [40,50,60]
|
||||
// [10,20,15,40,50,60]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Fill() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
s.Fill(2, 3, 99)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [10,20,99,99,99,50,60]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Chunk() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
r := s.Chunk(3)
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [[10 20 15] [30 40 50] [60]]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Pad() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
s.Pad(8, 99)
|
||||
fmt.Println(s)
|
||||
s.Pad(-10, 89)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60,99]
|
||||
// [89,89,10,20,15,30,40,50,60,99]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Rand() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Rand())
|
||||
|
||||
// May Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// 10 true
|
||||
}
|
||||
|
||||
func ExampleIntArray_Rands() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Rands(3))
|
||||
|
||||
// May Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [20 50 20]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Shuffle() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Shuffle())
|
||||
|
||||
// May Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [10,40,15,50,20,60,30]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Reverse() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Reverse())
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [60,50,40,30,15,20,10]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Join() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Join(","))
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// 10,20,15,30,40,50,60
|
||||
}
|
||||
|
||||
func ExampleIntArray_CountValues() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 15, 40, 40, 40})
|
||||
fmt.Println(s.CountValues())
|
||||
|
||||
// Output:
|
||||
// map[10:1 15:2 20:1 40:3]
|
||||
}
|
||||
|
||||
func ExampleIntArray_Iterator() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
s.Iterator(func(k int, v int) bool {
|
||||
fmt.Println(k, v)
|
||||
return true
|
||||
})
|
||||
|
||||
// Output:
|
||||
// 0 10
|
||||
// 1 20
|
||||
// 2 15
|
||||
// 3 30
|
||||
// 4 40
|
||||
// 5 50
|
||||
// 6 60
|
||||
}
|
||||
|
||||
func ExampleIntArray_IteratorAsc() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
s.IteratorAsc(func(k int, v int) bool {
|
||||
fmt.Println(k, v)
|
||||
return true
|
||||
})
|
||||
|
||||
// Output:
|
||||
// 0 10
|
||||
// 1 20
|
||||
// 2 15
|
||||
// 3 30
|
||||
// 4 40
|
||||
// 5 50
|
||||
// 6 60
|
||||
}
|
||||
|
||||
func ExampleIntArray_IteratorDesc() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
s.IteratorDesc(func(k int, v int) bool {
|
||||
fmt.Println(k, v)
|
||||
return true
|
||||
})
|
||||
|
||||
// Output:
|
||||
// 6 60
|
||||
// 5 50
|
||||
// 4 40
|
||||
// 3 30
|
||||
// 2 15
|
||||
// 1 20
|
||||
// 0 10
|
||||
}
|
||||
|
||||
func ExampleIntArray_String() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.String())
|
||||
|
||||
// Output:
|
||||
// [10,20,15,30,40,50,60]
|
||||
// [10,20,15,30,40,50,60]
|
||||
}
|
||||
|
||||
func ExampleIntArray_MarshalJSON() {
|
||||
type Student struct {
|
||||
Id int
|
||||
Name string
|
||||
Scores garray.IntArray
|
||||
}
|
||||
var array garray.IntArray
|
||||
array.SetArray(g.SliceInt{98, 97, 96})
|
||||
s := Student{
|
||||
Id: 1,
|
||||
Name: "john",
|
||||
Scores: array,
|
||||
}
|
||||
b, _ := json.Marshal(s)
|
||||
fmt.Println(string(b))
|
||||
|
||||
// Output:
|
||||
// {"Id":1,"Name":"john","Scores":[98,97,96]}
|
||||
}
|
||||
|
||||
func ExampleIntArray_UnmarshalJSON() {
|
||||
b := []byte(`{"Id":1,"Name":"john","Scores":[98,96,97]}`)
|
||||
type Student struct {
|
||||
Id int
|
||||
Name string
|
||||
Scores *garray.IntArray
|
||||
}
|
||||
s := Student{}
|
||||
json.Unmarshal(b, &s)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// {1 john [98,96,97]}
|
||||
}
|
||||
|
||||
func ExampleIntArray_UnmarshalValue() {
|
||||
type Student struct {
|
||||
Name string
|
||||
Scores *garray.IntArray
|
||||
}
|
||||
|
||||
var s *Student
|
||||
gconv.Struct(g.Map{
|
||||
"name": "john",
|
||||
"scores": g.SliceInt{96, 98, 97},
|
||||
}, &s)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// &{john [96,98,97]}
|
||||
}
|
||||
|
||||
func ExampleIntArray_FilterEmpty() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 40, 50, 0, 0, 0, 60})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.FilterEmpty())
|
||||
|
||||
// Output:
|
||||
// [10,40,50,0,0,0,60]
|
||||
// [10,40,50,60]
|
||||
}
|
||||
|
||||
func ExampleIntArray_IsEmpty() {
|
||||
s := garray.NewIntArrayFrom(g.SliceInt{10, 20, 15, 30, 40, 50, 60})
|
||||
fmt.Println(s.IsEmpty())
|
||||
s1 := garray.NewIntArray()
|
||||
fmt.Println(s1.IsEmpty())
|
||||
|
||||
// Output:
|
||||
// false
|
||||
// true
|
||||
}
|
||||
573
container/garray/garray_z_example_sorted_str_test.go
Normal file
573
container/garray/garray_z_example_sorted_str_test.go
Normal file
@ -0,0 +1,573 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). 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/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
func ExampleSortedStrArray_Walk() {
|
||||
var array garray.SortedStrArray
|
||||
tables := g.SliceStr{"user", "user_detail"}
|
||||
prefix := "gf_"
|
||||
array.Append(tables...)
|
||||
// Add prefix for given table names.
|
||||
array.Walk(func(value string) string {
|
||||
return prefix + value
|
||||
})
|
||||
fmt.Println(array.Slice())
|
||||
|
||||
// Output:
|
||||
// [gf_user gf_user_detail]
|
||||
}
|
||||
|
||||
func ExampleNewSortedStrArray() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.Append("b")
|
||||
s.Append("d")
|
||||
s.Append("c")
|
||||
s.Append("a")
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a b c d]
|
||||
}
|
||||
|
||||
func ExampleNewSortedStrArraySize() {
|
||||
s := garray.NewSortedStrArraySize(3)
|
||||
s.SetArray([]string{"b", "d", "a", "c"})
|
||||
fmt.Println(s.Slice(), s.Len(), cap(s.Slice()))
|
||||
|
||||
// Output:
|
||||
// [a b c d] 4 4
|
||||
}
|
||||
|
||||
func ExampleNewStrArrayFromCopy() {
|
||||
s := garray.NewSortedStrArrayFromCopy(g.SliceStr{"b", "d", "c", "a"})
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a b c d]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_At() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"b", "d", "c", "a"})
|
||||
sAt := s.At(2)
|
||||
fmt.Println(s)
|
||||
fmt.Println(sAt)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d"]
|
||||
// c
|
||||
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Get() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"b", "d", "c", "a", "e"})
|
||||
sGet, sBool := s.Get(3)
|
||||
fmt.Println(s)
|
||||
fmt.Println(sGet, sBool)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d","e"]
|
||||
// d true
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_SetArray() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray([]string{"b", "d", "a", "c"})
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a b c d]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_SetUnique() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray([]string{"b", "d", "a", "c", "c", "a"})
|
||||
fmt.Println(s.SetUnique(true))
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Sum() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray([]string{"5", "3", "2"})
|
||||
fmt.Println(s)
|
||||
a := s.Sum()
|
||||
fmt.Println(a)
|
||||
|
||||
// Output:
|
||||
// ["2","3","5"]
|
||||
// 10
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Sort() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"b", "d", "a", "c"})
|
||||
fmt.Println(s)
|
||||
a := s.Sort()
|
||||
fmt.Println(a)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d"]
|
||||
// ["a","b","c","d"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Remove() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"b", "d", "c", "a"})
|
||||
fmt.Println(s.Slice())
|
||||
s.Remove(1)
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a b c d]
|
||||
// [a c d]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_RemoveValue() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"b", "d", "c", "a"})
|
||||
fmt.Println(s.Slice())
|
||||
s.RemoveValue("b")
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a b c d]
|
||||
// [a c d]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_PopLeft() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"b", "d", "c", "a"})
|
||||
r, _ := s.PopLeft()
|
||||
fmt.Println(r)
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// a
|
||||
// [b c d]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_PopRight() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"b", "d", "c", "a"})
|
||||
fmt.Println(s.Slice())
|
||||
r, _ := s.PopRight()
|
||||
fmt.Println(r)
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a b c d]
|
||||
// d
|
||||
// [a b c]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_PopRights() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
r := s.PopRights(2)
|
||||
fmt.Println(r)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// [g h]
|
||||
// ["a","b","c","d","e","f"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Rand() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
r, _ := s.PopRand()
|
||||
fmt.Println(r)
|
||||
fmt.Println(s)
|
||||
|
||||
// May Output:
|
||||
// b
|
||||
// ["a","c","d","e","f","g","h"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_PopRands() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
r := s.PopRands(2)
|
||||
fmt.Println(r)
|
||||
fmt.Println(s)
|
||||
|
||||
// May Output:
|
||||
// [d a]
|
||||
// ["b","c","e","f","g","h"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_PopLefts() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
r := s.PopLefts(2)
|
||||
fmt.Println(r)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// [a b]
|
||||
// ["c","d","e","f","g","h"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Range() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
r := s.Range(2, 5)
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [c d e]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_SubSlice() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
r := s.SubSlice(3, 4)
|
||||
fmt.Println(s.Slice())
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [a b c d e f g h]
|
||||
// [d e f g]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Add() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.Add("b", "d", "c", "a")
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Append() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"b", "d", "c", "a"})
|
||||
fmt.Println(s)
|
||||
s.Append("f", "e", "g")
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d"]
|
||||
// ["a","b","c","d","e","f","g"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Len() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Len())
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d","e","f","g","h"]
|
||||
// 8
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Slice() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a b c d e f g h]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Interfaces() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
r := s.Interfaces()
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [a b c d e f g h]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Clone() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
r := s.Clone()
|
||||
fmt.Println(r)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d","e","f","g","h"]
|
||||
// ["a","b","c","d","e","f","g","h"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Clear() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Clear())
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d","e","f","g","h"]
|
||||
// []
|
||||
// []
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Contains() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
fmt.Println(s.Contains("e"))
|
||||
fmt.Println(s.Contains("E"))
|
||||
fmt.Println(s.Contains("z"))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_ContainsI() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.ContainsI("E"))
|
||||
fmt.Println(s.ContainsI("z"))
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d","e","f","g","h"]
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Search() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Search("e"))
|
||||
fmt.Println(s.Search("E"))
|
||||
fmt.Println(s.Search("z"))
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d","e","f","g","h"]
|
||||
// 4
|
||||
// -1
|
||||
// -1
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Unique() {
|
||||
s := garray.NewSortedStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "c", "c", "d", "d"})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Unique())
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","c","c","d","d"]
|
||||
// ["a","b","c","d"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_LockFunc() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"b", "c", "a"})
|
||||
s.LockFunc(func(array []string) {
|
||||
array[len(array)-1] = "GF fans"
|
||||
})
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// ["a","b","GF fans"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_RLockFunc() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"b", "c", "a"})
|
||||
s.RLockFunc(func(array []string) {
|
||||
array[len(array)-1] = "GF fans"
|
||||
fmt.Println(array[len(array)-1])
|
||||
})
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// GF fans
|
||||
// ["a","b","GF fans"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Merge() {
|
||||
s1 := garray.NewSortedStrArray()
|
||||
s2 := garray.NewSortedStrArray()
|
||||
s1.SetArray(g.SliceStr{"b", "c", "a"})
|
||||
s2.SetArray(g.SliceStr{"e", "d", "f"})
|
||||
fmt.Println(s1)
|
||||
fmt.Println(s2)
|
||||
s1.Merge(s2)
|
||||
fmt.Println(s1)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c"]
|
||||
// ["d","e","f"]
|
||||
// ["a","b","c","d","e","f"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Chunk() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
r := s.Chunk(3)
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [[a b c] [d e f] [g h]]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Rands() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Rands(3))
|
||||
|
||||
// May Output:
|
||||
// ["a","b","c","d","e","f","g","h"]
|
||||
// [h g c]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Join() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"c", "b", "a", "d", "f", "e", "h", "g"})
|
||||
fmt.Println(s.Join(","))
|
||||
|
||||
// Output:
|
||||
// a,b,c,d,e,f,g,h
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_CountValues() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"a", "b", "c", "c", "c", "d", "d"})
|
||||
fmt.Println(s.CountValues())
|
||||
|
||||
// Output:
|
||||
// map[a:1 b:1 c:3 d:2]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_Iterator() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"b", "c", "a"})
|
||||
s.Iterator(func(k int, v string) bool {
|
||||
fmt.Println(k, v)
|
||||
return true
|
||||
})
|
||||
|
||||
// Output:
|
||||
// 0 a
|
||||
// 1 b
|
||||
// 2 c
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_IteratorAsc() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"b", "c", "a"})
|
||||
s.IteratorAsc(func(k int, v string) bool {
|
||||
fmt.Println(k, v)
|
||||
return true
|
||||
})
|
||||
|
||||
// Output:
|
||||
// 0 a
|
||||
// 1 b
|
||||
// 2 c
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_IteratorDesc() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"b", "c", "a"})
|
||||
s.IteratorDesc(func(k int, v string) bool {
|
||||
fmt.Println(k, v)
|
||||
return true
|
||||
})
|
||||
|
||||
// Output:
|
||||
// 2 c
|
||||
// 1 b
|
||||
// 0 a
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_String() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"b", "c", "a"})
|
||||
fmt.Println(s.String())
|
||||
|
||||
// Output:
|
||||
// ["a","b","c"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_MarshalJSON() {
|
||||
type Student struct {
|
||||
ID int
|
||||
Name string
|
||||
Levels garray.SortedStrArray
|
||||
}
|
||||
r := garray.NewSortedStrArrayFrom(g.SliceStr{"b", "c", "a"})
|
||||
s := Student{
|
||||
ID: 1,
|
||||
Name: "john",
|
||||
Levels: *r,
|
||||
}
|
||||
b, _ := json.Marshal(s)
|
||||
fmt.Println(string(b))
|
||||
|
||||
// Output:
|
||||
// {"ID":1,"Name":"john","Levels":["a","b","c"]}
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_UnmarshalJSON() {
|
||||
b := []byte(`{"Id":1,"Name":"john","Lessons":["Math","English","Sport"]}`)
|
||||
type Student struct {
|
||||
Id int
|
||||
Name string
|
||||
Lessons *garray.StrArray
|
||||
}
|
||||
s := Student{}
|
||||
json.Unmarshal(b, &s)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// {1 john ["Math","English","Sport"]}
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_UnmarshalValue() {
|
||||
type Student struct {
|
||||
Name string
|
||||
Lessons *garray.StrArray
|
||||
}
|
||||
var s *Student
|
||||
gconv.Struct(g.Map{
|
||||
"name": "john",
|
||||
"lessons": []byte(`["Math","English","Sport"]`),
|
||||
}, &s)
|
||||
fmt.Println(s)
|
||||
|
||||
var s1 *Student
|
||||
gconv.Struct(g.Map{
|
||||
"name": "john",
|
||||
"lessons": g.SliceStr{"Math", "English", "Sport"},
|
||||
}, &s1)
|
||||
fmt.Println(s1)
|
||||
|
||||
// Output:
|
||||
// &{john ["Math","English","Sport"]}
|
||||
// &{john ["Math","English","Sport"]}
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_FilterEmpty() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"b", "a", "", "c", "", "", "d"})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.FilterEmpty())
|
||||
|
||||
// Output:
|
||||
// ["","","","a","b","c","d"]
|
||||
// ["a","b","c","d"]
|
||||
}
|
||||
|
||||
func ExampleSortedStrArray_IsEmpty() {
|
||||
s := garray.NewSortedStrArrayFrom(g.SliceStr{"b", "a", "", "c", "", "", "d"})
|
||||
fmt.Println(s.IsEmpty())
|
||||
s1 := garray.NewSortedStrArray()
|
||||
fmt.Println(s1.IsEmpty())
|
||||
|
||||
// Output:
|
||||
// false
|
||||
// true
|
||||
}
|
||||
@ -10,6 +10,9 @@ import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
func ExampleStrArray_Walk() {
|
||||
@ -26,3 +29,621 @@ func ExampleStrArray_Walk() {
|
||||
// Output:
|
||||
// [gf_user gf_user_detail]
|
||||
}
|
||||
|
||||
func ExampleStrArray_NewStrArray() {
|
||||
s := garray.NewStrArray()
|
||||
s.Append("We")
|
||||
s.Append("are")
|
||||
s.Append("GF")
|
||||
s.Append("fans")
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [We are GF fans]
|
||||
}
|
||||
|
||||
func ExampleStrArray_NewStrArraySize() {
|
||||
s := garray.NewStrArraySize(3, 5)
|
||||
s.Set(0, "We")
|
||||
s.Set(1, "are")
|
||||
s.Set(2, "GF")
|
||||
s.Set(3, "fans")
|
||||
fmt.Println(s.Slice(), s.Len(), cap(s.Slice()))
|
||||
|
||||
// Output:
|
||||
// [We are GF] 3 5
|
||||
}
|
||||
|
||||
func ExampleStrArray_NewStrArrayFrom() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"We", "are", "GF", "fans", "!"})
|
||||
fmt.Println(s.Slice(), s.Len(), cap(s.Slice()))
|
||||
|
||||
// Output:
|
||||
// [We are GF fans !] 5 5
|
||||
}
|
||||
|
||||
func ExampleStrArray_NewStrArrayFromCopy() {
|
||||
s := garray.NewStrArrayFromCopy(g.SliceStr{"We", "are", "GF", "fans", "!"})
|
||||
fmt.Println(s.Slice(), s.Len(), cap(s.Slice()))
|
||||
|
||||
// Output:
|
||||
// [We are GF fans !] 5 5
|
||||
}
|
||||
|
||||
func ExampleStrArray_At() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"We", "are", "GF", "fans", "!"})
|
||||
sAt := s.At(2)
|
||||
fmt.Println(sAt)
|
||||
|
||||
// Output:
|
||||
// GF
|
||||
}
|
||||
|
||||
func ExampleStrArray_Get() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"We", "are", "GF", "fans", "!"})
|
||||
sGet, sBool := s.Get(3)
|
||||
fmt.Println(sGet, sBool)
|
||||
|
||||
// Output:
|
||||
// fans true
|
||||
}
|
||||
|
||||
func ExampleStrArray_Set() {
|
||||
s := garray.NewStrArraySize(3, 5)
|
||||
s.Set(0, "We")
|
||||
s.Set(1, "are")
|
||||
s.Set(2, "GF")
|
||||
s.Set(3, "fans")
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [We are GF]
|
||||
}
|
||||
|
||||
func ExampleStrArray_SetArray() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"We", "are", "GF", "fans", "!"})
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [We are GF fans !]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Replace() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"We", "are", "GF", "fans", "!"})
|
||||
fmt.Println(s.Slice())
|
||||
s.Replace(g.SliceStr{"Happy", "coding"})
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [We are GF fans !]
|
||||
// [Happy coding GF fans !]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Sum() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"3", "5", "10"})
|
||||
a := s.Sum()
|
||||
fmt.Println(a)
|
||||
|
||||
// Output:
|
||||
// 18
|
||||
}
|
||||
|
||||
func ExampleStrArray_Sort() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"b", "d", "a", "c"})
|
||||
a := s.Sort()
|
||||
fmt.Println(a)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_SortFunc() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"b", "c", "a"})
|
||||
fmt.Println(s)
|
||||
s.SortFunc(func(v1, v2 string) bool {
|
||||
return gstr.Compare(v1, v2) > 0
|
||||
})
|
||||
fmt.Println(s)
|
||||
s.SortFunc(func(v1, v2 string) bool {
|
||||
return gstr.Compare(v1, v2) < 0
|
||||
})
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// ["b","c","a"]
|
||||
// ["c","b","a"]
|
||||
// ["a","b","c"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_InsertBefore() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d"})
|
||||
s.InsertBefore(1, "here")
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a here b c d]
|
||||
}
|
||||
|
||||
func ExampleStrArray_InsertAfter() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d"})
|
||||
s.InsertAfter(1, "here")
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a b here c d]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Remove() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d"})
|
||||
s.Remove(1)
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a c d]
|
||||
}
|
||||
|
||||
func ExampleStrArray_RemoveValue() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d"})
|
||||
s.RemoveValue("b")
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a c d]
|
||||
}
|
||||
|
||||
func ExampleStrArray_PushLeft() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d"})
|
||||
s.PushLeft("We", "are", "GF", "fans")
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [We are GF fans a b c d]
|
||||
}
|
||||
|
||||
func ExampleStrArray_PushRight() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d"})
|
||||
s.PushRight("We", "are", "GF", "fans")
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a b c d We are GF fans]
|
||||
}
|
||||
|
||||
func ExampleStrArray_PopLeft() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d"})
|
||||
s.PopLeft()
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [b c d]
|
||||
}
|
||||
|
||||
func ExampleStrArray_PopRight() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d"})
|
||||
s.PopRight()
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a b c]
|
||||
}
|
||||
|
||||
func ExampleStrArray_PopRand() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
r, _ := s.PopRand()
|
||||
fmt.Println(r)
|
||||
|
||||
// May Output:
|
||||
// e
|
||||
}
|
||||
|
||||
func ExampleStrArray_PopRands() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
r := s.PopRands(2)
|
||||
fmt.Println(r)
|
||||
|
||||
// May Output:
|
||||
// [e c]
|
||||
}
|
||||
|
||||
func ExampleStrArray_PopLefts() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
r := s.PopLefts(2)
|
||||
fmt.Println(r)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// [a b]
|
||||
// ["c","d","e","f","g","h"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_PopRights() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
r := s.PopRights(2)
|
||||
fmt.Println(r)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// [g h]
|
||||
// ["a","b","c","d","e","f"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Range() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
r := s.Range(2, 5)
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [c d e]
|
||||
}
|
||||
|
||||
func ExampleStrArray_SubSlice() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
r := s.SubSlice(3, 4)
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [d e f g]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Append() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"We", "are", "GF", "fans"})
|
||||
s.Append("a", "b", "c")
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// ["We","are","GF","fans","a","b","c"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Len() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
fmt.Println(s.Len())
|
||||
|
||||
// Output:
|
||||
// 8
|
||||
}
|
||||
|
||||
func ExampleStrArray_Slice() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
fmt.Println(s.Slice())
|
||||
|
||||
// Output:
|
||||
// [a b c d e f g h]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Interfaces() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
r := s.Interfaces()
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [a b c d e f g h]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Clone() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
r := s.Clone()
|
||||
fmt.Println(r)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d","e","f","g","h"]
|
||||
// ["a","b","c","d","e","f","g","h"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Clear() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
fmt.Println(s)
|
||||
fmt.Println(s.Clear())
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d","e","f","g","h"]
|
||||
// []
|
||||
// []
|
||||
}
|
||||
|
||||
func ExampleStrArray_Contains() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
fmt.Println(s.Contains("e"))
|
||||
fmt.Println(s.Contains("z"))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleStrArray_ContainsI() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
fmt.Println(s.ContainsI("E"))
|
||||
fmt.Println(s.ContainsI("z"))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleStrArray_Search() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
fmt.Println(s.Search("e"))
|
||||
fmt.Println(s.Search("z"))
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
// -1
|
||||
}
|
||||
|
||||
func ExampleStrArray_Unique() {
|
||||
s := garray.NewStrArray()
|
||||
s.SetArray(g.SliceStr{"a", "b", "c", "c", "c", "d", "d"})
|
||||
fmt.Println(s.Unique())
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_LockFunc() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c"})
|
||||
s.LockFunc(func(array []string) {
|
||||
array[len(array)-1] = "GF fans"
|
||||
})
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// ["a","b","GF fans"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_RLockFunc() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c", "d", "e"})
|
||||
s.RLockFunc(func(array []string) {
|
||||
for i := 0; i < len(array); i++ {
|
||||
fmt.Println(array[i])
|
||||
}
|
||||
})
|
||||
|
||||
// Output:
|
||||
// a
|
||||
// b
|
||||
// c
|
||||
// d
|
||||
// e
|
||||
}
|
||||
|
||||
func ExampleStrArray_Merge() {
|
||||
s1 := garray.NewStrArray()
|
||||
s2 := garray.NewStrArray()
|
||||
s1.SetArray(g.SliceStr{"a", "b", "c"})
|
||||
s2.SetArray(g.SliceStr{"d", "e", "f"})
|
||||
s1.Merge(s2)
|
||||
fmt.Println(s1)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d","e","f"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Fill() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
s.Fill(2, 3, "here")
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// ["a","b","here","here","here","f","g","h"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Chunk() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
r := s.Chunk(3)
|
||||
fmt.Println(r)
|
||||
|
||||
// Output:
|
||||
// [[a b c] [d e f] [g h]]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Pad() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c"})
|
||||
s.Pad(7, "here")
|
||||
fmt.Println(s)
|
||||
s.Pad(-10, "there")
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","here","here","here","here"]
|
||||
// ["there","there","there","a","b","c","here","here","here","here"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Rand() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
fmt.Println(s.Rand())
|
||||
|
||||
// May Output:
|
||||
// c true
|
||||
}
|
||||
|
||||
func ExampleStrArray_Rands() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
fmt.Println(s.Rands(3))
|
||||
|
||||
// May Output:
|
||||
// [e h e]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Shuffle() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
fmt.Println(s.Shuffle())
|
||||
|
||||
// May Output:
|
||||
// ["a","c","e","d","b","g","f","h"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Reverse() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c", "d", "e", "f", "g", "h"})
|
||||
fmt.Println(s.Reverse())
|
||||
|
||||
// Output:
|
||||
// ["h","g","f","e","d","c","b","a"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Join() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c"})
|
||||
fmt.Println(s.Join(","))
|
||||
|
||||
// Output:
|
||||
// a,b,c
|
||||
}
|
||||
|
||||
func ExampleStrArray_CountValues() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c", "c", "c", "d", "d"})
|
||||
fmt.Println(s.CountValues())
|
||||
|
||||
// Output:
|
||||
// map[a:1 b:1 c:3 d:2]
|
||||
}
|
||||
|
||||
func ExampleStrArray_Iterator() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c"})
|
||||
s.Iterator(func(k int, v string) bool {
|
||||
fmt.Println(k, v)
|
||||
return true
|
||||
})
|
||||
|
||||
// Output:
|
||||
// 0 a
|
||||
// 1 b
|
||||
// 2 c
|
||||
}
|
||||
|
||||
func ExampleStrArray_IteratorAsc() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c"})
|
||||
s.IteratorAsc(func(k int, v string) bool {
|
||||
fmt.Println(k, v)
|
||||
return true
|
||||
})
|
||||
|
||||
// Output:
|
||||
// 0 a
|
||||
// 1 b
|
||||
// 2 c
|
||||
}
|
||||
|
||||
func ExampleStrArray_IteratorDesc() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c"})
|
||||
s.IteratorDesc(func(k int, v string) bool {
|
||||
fmt.Println(k, v)
|
||||
return true
|
||||
})
|
||||
|
||||
// Output:
|
||||
// 2 c
|
||||
// 1 b
|
||||
// 0 a
|
||||
}
|
||||
|
||||
func ExampleStrArray_String() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "c"})
|
||||
fmt.Println(s.String())
|
||||
|
||||
// Output:
|
||||
// ["a","b","c"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_MarshalJSON() {
|
||||
type Student struct {
|
||||
Id int
|
||||
Name string
|
||||
Lessons []string
|
||||
}
|
||||
s := Student{
|
||||
Id: 1,
|
||||
Name: "john",
|
||||
Lessons: []string{"Math", "English", "Music"},
|
||||
}
|
||||
b, _ := json.Marshal(s)
|
||||
fmt.Println(string(b))
|
||||
|
||||
// Output:
|
||||
// {"Id":1,"Name":"john","Lessons":["Math","English","Music"]}
|
||||
}
|
||||
|
||||
func ExampleStrArray_UnmarshalJSON() {
|
||||
b := []byte(`{"Id":1,"Name":"john","Lessons":["Math","English","Sport"]}`)
|
||||
type Student struct {
|
||||
Id int
|
||||
Name string
|
||||
Lessons *garray.StrArray
|
||||
}
|
||||
s := Student{}
|
||||
json.Unmarshal(b, &s)
|
||||
fmt.Println(s)
|
||||
|
||||
// Output:
|
||||
// {1 john ["Math","English","Sport"]}
|
||||
}
|
||||
|
||||
func ExampleStrArray_UnmarshalValue() {
|
||||
type Student struct {
|
||||
Name string
|
||||
Lessons *garray.StrArray
|
||||
}
|
||||
var s *Student
|
||||
gconv.Struct(g.Map{
|
||||
"name": "john",
|
||||
"lessons": []byte(`["Math","English","Sport"]`),
|
||||
}, &s)
|
||||
fmt.Println(s)
|
||||
|
||||
var s1 *Student
|
||||
gconv.Struct(g.Map{
|
||||
"name": "john",
|
||||
"lessons": g.SliceStr{"Math", "English", "Sport"},
|
||||
}, &s1)
|
||||
fmt.Println(s1)
|
||||
|
||||
// Output:
|
||||
// &{john ["Math","English","Sport"]}
|
||||
// &{john ["Math","English","Sport"]}
|
||||
}
|
||||
|
||||
func ExampleStrArray_FilterEmpty() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "", "c", "", "", "d"})
|
||||
fmt.Println(s.FilterEmpty())
|
||||
|
||||
// Output:
|
||||
// ["a","b","c","d"]
|
||||
}
|
||||
|
||||
func ExampleStrArray_IsEmpty() {
|
||||
s := garray.NewStrArrayFrom(g.SliceStr{"a", "b", "", "c", "", "", "d"})
|
||||
fmt.Println(s.IsEmpty())
|
||||
s1 := garray.NewStrArray()
|
||||
fmt.Println(s1.IsEmpty())
|
||||
|
||||
// Output:
|
||||
// false
|
||||
// true
|
||||
}
|
||||
|
||||
@ -7,17 +7,401 @@
|
||||
package gset_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/container/gset"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// New create and returns a new set, which contains un-repeated items.
|
||||
// The parameter `safe` is used to specify whether using set in concurrent-safety,
|
||||
// which is false in default.
|
||||
func ExampleNewIntSet() {
|
||||
intSet := gset.NewIntSet()
|
||||
intSet.Add([]int{1, 2, 3}...)
|
||||
fmt.Println(intSet.Slice())
|
||||
|
||||
// May Output:
|
||||
// [2 1 3]
|
||||
}
|
||||
|
||||
// NewIntSetFrom returns a new set from `items`.
|
||||
func ExampleNewFrom() {
|
||||
intSet := gset.NewIntSetFrom([]int{1, 2, 3})
|
||||
fmt.Println(intSet.Slice())
|
||||
|
||||
// May Output:
|
||||
// [2 1 3]
|
||||
}
|
||||
|
||||
// Add adds one or multiple items to the set.
|
||||
func ExampleIntSet_Add() {
|
||||
intSet := gset.NewIntSetFrom([]int{1, 2, 3})
|
||||
intSet.Add(1)
|
||||
fmt.Println(intSet.Slice())
|
||||
fmt.Println(intSet.AddIfNotExist(1))
|
||||
|
||||
// Mya Output:
|
||||
// [1 2 3]
|
||||
// false
|
||||
}
|
||||
|
||||
// AddIfNotExist checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set,
|
||||
// or else it does nothing and returns false.
|
||||
func ExampleIntSet_AddIfNotExist() {
|
||||
intSet := gset.NewIntSetFrom([]int{1, 2, 3})
|
||||
intSet.Add(1)
|
||||
fmt.Println(intSet.Slice())
|
||||
fmt.Println(intSet.AddIfNotExist(1))
|
||||
|
||||
// Mya Output:
|
||||
// [1 2 3]
|
||||
// false
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set and function `f` returns true,
|
||||
// or else it does nothing and returns false.
|
||||
// Note that, the function `f` is executed without writing lock.
|
||||
func ExampleIntSet_AddIfNotExistFunc() {
|
||||
intSet := gset.NewIntSetFrom([]int{1, 2, 3})
|
||||
intSet.Add(1)
|
||||
fmt.Println(intSet.Slice())
|
||||
fmt.Println(intSet.AddIfNotExistFunc(5, func() bool {
|
||||
return true
|
||||
}))
|
||||
|
||||
// May Output:
|
||||
// [1 2 3]
|
||||
// true
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set and function `f` returns true,
|
||||
// or else it does nothing and returns false.
|
||||
// Note that, the function `f` is executed without writing lock.
|
||||
func ExampleIntSet_AddIfNotExistFuncLock() {
|
||||
intSet := gset.NewIntSetFrom([]int{1, 2, 3})
|
||||
intSet.Add(1)
|
||||
fmt.Println(intSet.Slice())
|
||||
fmt.Println(intSet.AddIfNotExistFuncLock(4, func() bool {
|
||||
return true
|
||||
}))
|
||||
|
||||
// May Output:
|
||||
// [1 2 3]
|
||||
// true
|
||||
}
|
||||
|
||||
// Clear deletes all items of the set.
|
||||
func ExampleIntSet_Clear() {
|
||||
intSet := gset.NewIntSetFrom([]int{1, 2, 3})
|
||||
fmt.Println(intSet.Size())
|
||||
intSet.Clear()
|
||||
fmt.Println(intSet.Size())
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
// 0
|
||||
}
|
||||
|
||||
// Complement returns a new set which is the complement from `set` to `full`.
|
||||
// Which means, all the items in `newSet` are in `full` and not in `set`.
|
||||
// It returns the difference between `full` and `set` if the given set `full` is not the full set of `set`.
|
||||
func ExampleIntSet_Complement() {
|
||||
intSet := gset.NewIntSetFrom([]int{1, 2, 3, 4, 5})
|
||||
s := gset.NewIntSetFrom([]int{1, 2, 3})
|
||||
fmt.Println(s.Complement(intSet).Slice())
|
||||
|
||||
// May Output:
|
||||
// [4 5]
|
||||
}
|
||||
|
||||
// Contains checks whether the set contains `item`.
|
||||
func ExampleIntSet_Contains() {
|
||||
var set gset.IntSet
|
||||
set.Add(1)
|
||||
fmt.Println(set.Contains(1))
|
||||
fmt.Println(set.Contains(2))
|
||||
var set1 gset.IntSet
|
||||
set1.Add(1, 4, 5, 6, 7)
|
||||
fmt.Println(set1.Contains(1))
|
||||
|
||||
var set2 gset.IntSet
|
||||
set2.Add(1, 4, 5, 6, 7)
|
||||
fmt.Println(set2.Contains(8))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
// Diff returns a new set which is the difference set from `set` to `other`.
|
||||
// Which means, all the items in `newSet` are in `set` but not in `other`.
|
||||
func ExampleIntSet_Diff() {
|
||||
s1 := gset.NewIntSetFrom([]int{1, 2, 3})
|
||||
s2 := gset.NewIntSetFrom([]int{1, 2, 3, 4})
|
||||
fmt.Println(s2.Diff(s1).Slice())
|
||||
|
||||
// Output:
|
||||
// [4]
|
||||
}
|
||||
|
||||
// Equal checks whether the two sets equal.
|
||||
func ExampleIntSet_Equal() {
|
||||
s1 := gset.NewIntSetFrom([]int{1, 2, 3})
|
||||
s2 := gset.NewIntSetFrom([]int{1, 2, 3, 4})
|
||||
fmt.Println(s2.Equal(s1))
|
||||
|
||||
s3 := gset.NewIntSetFrom([]int{1, 2, 3})
|
||||
s4 := gset.NewIntSetFrom([]int{1, 2, 3})
|
||||
fmt.Println(s3.Equal(s4))
|
||||
|
||||
// Output:
|
||||
// false
|
||||
// true
|
||||
}
|
||||
|
||||
// Intersect returns a new set which is the intersection from `set` to `other`.
|
||||
// Which means, all the items in `newSet` are in `set` and also in `other`.
|
||||
func ExampleIntSet_Intersect() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3}...)
|
||||
var s2 gset.IntSet
|
||||
s2.Add([]int{1, 2, 3, 4}...)
|
||||
fmt.Println(s2.Intersect(s1).Slice())
|
||||
|
||||
// May Output:
|
||||
// [1 2 3]
|
||||
}
|
||||
|
||||
// IsSubsetOf checks whether the current set is a sub-set of `other`
|
||||
func ExampleIntSet_IsSubsetOf() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
var s2 gset.IntSet
|
||||
s2.Add([]int{1, 2, 4}...)
|
||||
fmt.Println(s2.IsSubsetOf(s1))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
}
|
||||
|
||||
// Iterator iterates the set readonly with given callback function `f`,
|
||||
// if `f` returns true then continue iterating; or false to stop.
|
||||
func ExampleIntSet_Iterator() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
s1.Iterator(func(v int) bool {
|
||||
fmt.Println("Iterator", v)
|
||||
return true
|
||||
})
|
||||
// May Output:
|
||||
// Iterator 2
|
||||
// Iterator 3
|
||||
// Iterator 1
|
||||
// Iterator 4
|
||||
}
|
||||
|
||||
// Join joins items with a string `glue`.
|
||||
func ExampleIntSet_Join() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
fmt.Println(s1.Join(","))
|
||||
|
||||
// May Output:
|
||||
// 3,4,1,2
|
||||
}
|
||||
|
||||
// LockFunc locks writing with callback function `f`.
|
||||
func ExampleIntSet_LockFunc() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2}...)
|
||||
s1.LockFunc(func(m map[int]struct{}) {
|
||||
m[3] = struct{}{}
|
||||
})
|
||||
fmt.Println(s1.Slice())
|
||||
|
||||
// May Output
|
||||
// [2 3 1]
|
||||
}
|
||||
|
||||
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
|
||||
func ExampleIntSet_MarshalJSON() {
|
||||
type Student struct {
|
||||
Id int
|
||||
Name string
|
||||
Scores *gset.IntSet
|
||||
}
|
||||
s := Student{
|
||||
Id: 1,
|
||||
Name: "john",
|
||||
Scores: gset.NewIntSetFrom([]int{100, 99, 98}),
|
||||
}
|
||||
b, _ := json.Marshal(s)
|
||||
fmt.Println(string(b))
|
||||
|
||||
// May Output:
|
||||
// {"Id":1,"Name":"john","Scores":[100,99,98]}
|
||||
}
|
||||
|
||||
// Merge adds items from `others` sets into `set`.
|
||||
func ExampleIntSet_Merge() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
|
||||
s2 := gset.NewIntSet()
|
||||
fmt.Println(s1.Merge(s2).Slice())
|
||||
|
||||
// May Output:
|
||||
// [1 2 3 4]
|
||||
}
|
||||
|
||||
// Pops randomly pops an item from set.
|
||||
func ExampleIntSet_Pop() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
|
||||
fmt.Println(s1.Pop())
|
||||
|
||||
// May Output:
|
||||
// 1
|
||||
}
|
||||
|
||||
// Pops randomly pops `size` items from set.
|
||||
// It returns all items if size == -1.
|
||||
func ExampleIntSet_Pops() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
for _, v := range s1.Pops(2) {
|
||||
fmt.Println(v)
|
||||
}
|
||||
|
||||
// May Output:
|
||||
// 1
|
||||
// 2
|
||||
}
|
||||
|
||||
// RLockFunc locks reading with callback function `f`.
|
||||
func ExampleIntSet_RLockFunc() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
s1.RLockFunc(func(m map[int]struct{}) {
|
||||
fmt.Println(m)
|
||||
})
|
||||
|
||||
// Output:
|
||||
// map[1:{} 2:{} 3:{} 4:{}]
|
||||
}
|
||||
|
||||
// Remove deletes `item` from set.
|
||||
func ExampleIntSet_Remove() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
s1.Remove(1)
|
||||
fmt.Println(s1.Slice())
|
||||
|
||||
// May Output:
|
||||
// [3 4 2]
|
||||
}
|
||||
|
||||
// Size returns the size of the set.
|
||||
func ExampleIntSet_Size() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
fmt.Println(s1.Size())
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
}
|
||||
|
||||
// Slice returns the a of items of the set as slice.
|
||||
func ExampleIntSet_Slice() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
fmt.Println(s1.Slice())
|
||||
|
||||
// May Output:
|
||||
// [1, 2, 3, 4]
|
||||
}
|
||||
|
||||
// String returns items as a string, which implements like json.Marshal does.
|
||||
func ExampleIntSet_String() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
fmt.Println(s1.String())
|
||||
|
||||
// May Output:
|
||||
// [1,2,3,4]
|
||||
}
|
||||
|
||||
// Sum sums items. Note: The items should be converted to int type,
|
||||
// or you'd get a result that you unexpected.
|
||||
func ExampleIntSet_Sum() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
fmt.Println(s1.Sum())
|
||||
|
||||
// Output:
|
||||
// 10
|
||||
}
|
||||
|
||||
// Union returns a new set which is the union of `set` and `other`.
|
||||
// Which means, all the items in `newSet` are in `set` or in `other`.
|
||||
func ExampleIntSet_Union() {
|
||||
s1 := gset.NewIntSet()
|
||||
s1.Add([]int{1, 2, 3, 4}...)
|
||||
s2 := gset.NewIntSet()
|
||||
s2.Add([]int{1, 2, 4}...)
|
||||
fmt.Println(s1.Union(s2).Slice())
|
||||
|
||||
// May Output:
|
||||
// [3 4 1 2]
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
|
||||
func ExampleIntSet_UnmarshalJSON() {
|
||||
b := []byte(`{"Id":1,"Name":"john","Scores":[100,99,98]}`)
|
||||
type Student struct {
|
||||
Id int
|
||||
Name string
|
||||
Scores *gset.IntSet
|
||||
}
|
||||
s := Student{}
|
||||
json.Unmarshal(b, &s)
|
||||
fmt.Println(s)
|
||||
|
||||
// May Output:
|
||||
// {1 john [100,99,98]}
|
||||
}
|
||||
|
||||
// UnmarshalValue is an interface implement which sets any type of value for set.
|
||||
func ExampleIntSet_UnmarshalValue() {
|
||||
b := []byte(`{"Id":1,"Name":"john","Scores":100,99,98}`)
|
||||
type Student struct {
|
||||
Id int
|
||||
Name string
|
||||
Scores *gset.IntSet
|
||||
}
|
||||
s := Student{}
|
||||
json.Unmarshal(b, &s)
|
||||
fmt.Println(s)
|
||||
|
||||
// May Output:
|
||||
// {1 john [100,99,98]}
|
||||
}
|
||||
|
||||
// Walk applies a user supplied function `f` to every item of set.
|
||||
func ExampleIntSet_Walk() {
|
||||
var (
|
||||
set gset.IntSet
|
||||
names = g.SliceInt{1, 0}
|
||||
delta = 10
|
||||
)
|
||||
set.Add(names...)
|
||||
// Add prefix for given table names.
|
||||
set.Walk(func(item int) int {
|
||||
return delta + item
|
||||
})
|
||||
fmt.Println(set.Slice())
|
||||
|
||||
// May Output:
|
||||
// [12 60]
|
||||
}
|
||||
|
||||
@ -7,24 +7,400 @@
|
||||
package gset_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/container/gset"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// NewStrSet create and returns a new set, which contains un-repeated items.
|
||||
// The parameter `safe` is used to specify whether using set in concurrent-safety,
|
||||
// which is false in default.
|
||||
func ExampleNewStrSet() {
|
||||
strSet := gset.NewStrSet(true)
|
||||
strSet.Add([]string{"str1", "str2", "str3"}...)
|
||||
fmt.Println(strSet.Slice())
|
||||
|
||||
// May Output:
|
||||
// [str3 str1 str2]
|
||||
}
|
||||
|
||||
// NewStrSetFrom returns a new set from `items`.
|
||||
func ExampleNewStrSetFrom() {
|
||||
strSet := gset.NewStrSetFrom([]string{"str1", "str2", "str3"}, true)
|
||||
fmt.Println(strSet.Slice())
|
||||
|
||||
// May Output:
|
||||
// [str1 str2 str3]
|
||||
}
|
||||
|
||||
// Add adds one or multiple items to the set.
|
||||
func ExampleStrSet_Add() {
|
||||
strSet := gset.NewStrSetFrom([]string{"str1", "str2", "str3"}, true)
|
||||
strSet.Add("str")
|
||||
fmt.Println(strSet.Slice())
|
||||
fmt.Println(strSet.AddIfNotExist("str"))
|
||||
|
||||
// Mya Output:
|
||||
// [str str1 str2 str3]
|
||||
// false
|
||||
}
|
||||
|
||||
// AddIfNotExist checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set,
|
||||
// or else it does nothing and returns false.
|
||||
func ExampleStrSet_AddIfNotExist() {
|
||||
strSet := gset.NewStrSetFrom([]string{"str1", "str2", "str3"}, true)
|
||||
strSet.Add("str")
|
||||
fmt.Println(strSet.Slice())
|
||||
fmt.Println(strSet.AddIfNotExist("str"))
|
||||
|
||||
// Mya Output:
|
||||
// [str str1 str2 str3]
|
||||
// false
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set and function `f` returns true,
|
||||
// or else it does nothing and returns false.
|
||||
// Note that, the function `f` is executed without writing lock.
|
||||
func ExampleStrSet_AddIfNotExistFunc() {
|
||||
strSet := gset.NewStrSetFrom([]string{"str1", "str2", "str3"}, true)
|
||||
strSet.Add("str")
|
||||
fmt.Println(strSet.Slice())
|
||||
fmt.Println(strSet.AddIfNotExistFunc("str5", func() bool {
|
||||
return true
|
||||
}))
|
||||
|
||||
// May Output:
|
||||
// [str1 str2 str3 str]
|
||||
// true
|
||||
}
|
||||
|
||||
// AddIfNotExistFunc checks whether item exists in the set,
|
||||
// it adds the item to set and returns true if it does not exists in the set and function `f` returns true,
|
||||
// or else it does nothing and returns false.
|
||||
// Note that, the function `f` is executed without writing lock.
|
||||
func ExampleStrSet_AddIfNotExistFuncLock() {
|
||||
strSet := gset.NewStrSetFrom([]string{"str1", "str2", "str3"}, true)
|
||||
strSet.Add("str")
|
||||
fmt.Println(strSet.Slice())
|
||||
fmt.Println(strSet.AddIfNotExistFuncLock("str4", func() bool {
|
||||
return true
|
||||
}))
|
||||
|
||||
// May Output:
|
||||
// [str1 str2 str3 str]
|
||||
// true
|
||||
}
|
||||
|
||||
// Clear deletes all items of the set.
|
||||
func ExampleStrSet_Clear() {
|
||||
strSet := gset.NewStrSetFrom([]string{"str1", "str2", "str3"}, true)
|
||||
fmt.Println(strSet.Size())
|
||||
strSet.Clear()
|
||||
fmt.Println(strSet.Size())
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
// 0
|
||||
}
|
||||
|
||||
// Complement returns a new set which is the complement from `set` to `full`.
|
||||
// Which means, all the items in `newSet` are in `full` and not in `set`.
|
||||
// It returns the difference between `full` and `set` if the given set `full` is not the full set of `set`.
|
||||
func ExampleStrSet_Complement() {
|
||||
strSet := gset.NewStrSetFrom([]string{"str1", "str2", "str3", "str4", "str5"}, true)
|
||||
s := gset.NewStrSetFrom([]string{"str1", "str2", "str3"}, true)
|
||||
fmt.Println(s.Complement(strSet).Slice())
|
||||
|
||||
// May Output:
|
||||
// [str4 str5]
|
||||
}
|
||||
|
||||
// Contains checks whether the set contains `item`.
|
||||
func ExampleStrSet_Contains() {
|
||||
var set gset.StrSet
|
||||
set.Add("a")
|
||||
fmt.Println(set.Contains("a"))
|
||||
fmt.Println(set.Contains("A"))
|
||||
fmt.Println(set.ContainsI("A"))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
// ContainsI checks whether a value exists in the set with case-insensitively.
|
||||
// Note that it internally iterates the whole set to do the comparison with case-insensitively.
|
||||
func ExampleStrSet_ContainsI() {
|
||||
var set gset.StrSet
|
||||
set.Add("a")
|
||||
fmt.Println(set.ContainsI("a"))
|
||||
fmt.Println(set.ContainsI("A"))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
}
|
||||
|
||||
// Diff returns a new set which is the difference set from `set` to `other`.
|
||||
// Which means, all the items in `newSet` are in `set` but not in `other`.
|
||||
func ExampleStrSet_Diff() {
|
||||
s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
|
||||
s2 := gset.NewStrSetFrom([]string{"a", "b", "c", "d"}, true)
|
||||
fmt.Println(s2.Diff(s1).Slice())
|
||||
|
||||
// Output:
|
||||
// [d]
|
||||
}
|
||||
|
||||
// Equal checks whether the two sets equal.
|
||||
func ExampleStrSet_Equal() {
|
||||
s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
|
||||
s2 := gset.NewStrSetFrom([]string{"a", "b", "c", "d"}, true)
|
||||
fmt.Println(s2.Equal(s1))
|
||||
|
||||
s3 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
|
||||
s4 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
|
||||
fmt.Println(s3.Equal(s4))
|
||||
|
||||
// Output:
|
||||
// false
|
||||
// true
|
||||
}
|
||||
|
||||
// Intersect returns a new set which is the intersection from `set` to `other`.
|
||||
// Which means, all the items in `newSet` are in `set` and also in `other`.
|
||||
func ExampleStrSet_Intersect() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c"}...)
|
||||
var s2 gset.StrSet
|
||||
s2.Add([]string{"a", "b", "c", "d"}...)
|
||||
fmt.Println(s2.Intersect(s1).Slice())
|
||||
|
||||
// May Output:
|
||||
// [c a b]
|
||||
}
|
||||
|
||||
// IsSubsetOf checks whether the current set is a sub-set of `other`
|
||||
func ExampleStrSet_IsSubsetOf() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c", "d"}...)
|
||||
var s2 gset.StrSet
|
||||
s2.Add([]string{"a", "b", "d"}...)
|
||||
fmt.Println(s2.IsSubsetOf(s1))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
}
|
||||
|
||||
// Iterator iterates the set readonly with given callback function `f`,
|
||||
// if `f` returns true then continue iterating; or false to stop.
|
||||
func ExampleStrSet_Iterator() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c", "d"}...)
|
||||
s1.Iterator(func(v string) bool {
|
||||
fmt.Println("Iterator", v)
|
||||
return true
|
||||
})
|
||||
|
||||
// May Output:
|
||||
// Iterator a
|
||||
// Iterator b
|
||||
// Iterator c
|
||||
// Iterator d
|
||||
}
|
||||
|
||||
// Join joins items with a string `glue`.
|
||||
func ExampleStrSet_Join() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c", "d"}...)
|
||||
fmt.Println(s1.Join(","))
|
||||
|
||||
// May Output:
|
||||
// b,c,d,a
|
||||
}
|
||||
|
||||
// LockFunc locks writing with callback function `f`.
|
||||
func ExampleStrSet_LockFunc() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"1", "2"}...)
|
||||
s1.LockFunc(func(m map[string]struct{}) {
|
||||
m["3"] = struct{}{}
|
||||
})
|
||||
fmt.Println(s1.Slice())
|
||||
|
||||
// May Output
|
||||
// [2 3 1]
|
||||
|
||||
}
|
||||
|
||||
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
|
||||
func ExampleStrSet_MarshalJSON() {
|
||||
type Student struct {
|
||||
Id int
|
||||
Name string
|
||||
Scores *gset.StrSet
|
||||
}
|
||||
s := Student{
|
||||
Id: 1,
|
||||
Name: "john",
|
||||
Scores: gset.NewStrSetFrom([]string{"100", "99", "98"}, true),
|
||||
}
|
||||
b, _ := json.Marshal(s)
|
||||
fmt.Println(string(b))
|
||||
|
||||
// May Output:
|
||||
// {"Id":1,"Name":"john","Scores":["100","99","98"]}
|
||||
}
|
||||
|
||||
// Merge adds items from `others` sets into `set`.
|
||||
func ExampleStrSet_Merge() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c", "d"}...)
|
||||
|
||||
s2 := gset.NewStrSet(true)
|
||||
fmt.Println(s1.Merge(s2).Slice())
|
||||
|
||||
// May Output:
|
||||
// [d a b c]
|
||||
}
|
||||
|
||||
// Pops randomly pops an item from set.
|
||||
func ExampleStrSet_Pop() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c", "d"}...)
|
||||
|
||||
fmt.Println(s1.Pop())
|
||||
|
||||
// May Output:
|
||||
// a
|
||||
}
|
||||
|
||||
// Pops randomly pops `size` items from set.
|
||||
// It returns all items if size == -1.
|
||||
func ExampleStrSet_Pops() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c", "d"}...)
|
||||
for _, v := range s1.Pops(2) {
|
||||
fmt.Println(v)
|
||||
}
|
||||
|
||||
// May Output:
|
||||
// a
|
||||
// b
|
||||
}
|
||||
|
||||
// RLockFunc locks reading with callback function `f`.
|
||||
func ExampleStrSet_RLockFunc() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c", "d"}...)
|
||||
s1.RLockFunc(func(m map[string]struct{}) {
|
||||
fmt.Println(m)
|
||||
})
|
||||
|
||||
// Output:
|
||||
// map[a:{} b:{} c:{} d:{}]
|
||||
}
|
||||
|
||||
// Remove deletes `item` from set.
|
||||
func ExampleStrSet_Remove() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c", "d"}...)
|
||||
s1.Remove("a")
|
||||
fmt.Println(s1.Slice())
|
||||
|
||||
// May Output:
|
||||
// [b c d]
|
||||
}
|
||||
|
||||
// Size returns the size of the set.
|
||||
func ExampleStrSet_Size() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c", "d"}...)
|
||||
fmt.Println(s1.Size())
|
||||
|
||||
// Output:
|
||||
// 4
|
||||
}
|
||||
|
||||
// Slice returns the a of items of the set as slice.
|
||||
func ExampleStrSet_Slice() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c", "d"}...)
|
||||
fmt.Println(s1.Slice())
|
||||
|
||||
// May Output:
|
||||
// [a,b,c,d]
|
||||
}
|
||||
|
||||
// String returns items as a string, which implements like json.Marshal does.
|
||||
func ExampleStrSet_String() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c", "d"}...)
|
||||
fmt.Println(s1.String())
|
||||
|
||||
// May Output:
|
||||
// "a","b","c","d"
|
||||
}
|
||||
|
||||
// Sum sums items. Note: The items should be converted to int type,
|
||||
// or you'd get a result that you unexpected.
|
||||
func ExampleStrSet_Sum() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"1", "2", "3", "4"}...)
|
||||
fmt.Println(s1.Sum())
|
||||
|
||||
// Output:
|
||||
// 10
|
||||
}
|
||||
|
||||
// Union returns a new set which is the union of `set` and `other`.
|
||||
// Which means, all the items in `newSet` are in `set` or in `other`.
|
||||
func ExampleStrSet_Union() {
|
||||
s1 := gset.NewStrSet(true)
|
||||
s1.Add([]string{"a", "b", "c", "d"}...)
|
||||
s2 := gset.NewStrSet(true)
|
||||
s2.Add([]string{"a", "b", "d"}...)
|
||||
fmt.Println(s1.Union(s2).Slice())
|
||||
|
||||
// May Output:
|
||||
// [a b c d]
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
|
||||
func ExampleStrSet_UnmarshalJSON() {
|
||||
b := []byte(`{"Id":1,"Name":"john","Scores":["100","99","98"]}`)
|
||||
type Student struct {
|
||||
Id int
|
||||
Name string
|
||||
Scores *gset.StrSet
|
||||
}
|
||||
s := Student{}
|
||||
json.Unmarshal(b, &s)
|
||||
fmt.Println(s)
|
||||
|
||||
// May Output:
|
||||
// {1 john "99","98","100"}
|
||||
}
|
||||
|
||||
// UnmarshalValue is an interface implement which sets any type of value for set.
|
||||
func ExampleStrSet_UnmarshalValue() {
|
||||
b := []byte(`{"Id":1,"Name":"john","Scores":["100","99","98"]}`)
|
||||
type Student struct {
|
||||
Id int
|
||||
Name string
|
||||
Scores *gset.StrSet
|
||||
}
|
||||
s := Student{}
|
||||
json.Unmarshal(b, &s)
|
||||
fmt.Println(s)
|
||||
|
||||
// May Output:
|
||||
// {1 john "99","98","100"}
|
||||
}
|
||||
|
||||
// Walk applies a user supplied function `f` to every item of set.
|
||||
func ExampleStrSet_Walk() {
|
||||
var (
|
||||
set gset.StrSet
|
||||
|
||||
@ -642,7 +642,7 @@ func (c *Core) writeSqlToLogger(ctx context.Context, sql *Sql) {
|
||||
}
|
||||
}
|
||||
s := fmt.Sprintf(
|
||||
"[%3d ms] [%s] [%s:%d] %s%s",
|
||||
"[%3d ms] [%s] [%s:%-3d] %s%s",
|
||||
sql.End-sql.Start, sql.Group, sqlTypeKey, sql.RowsAffected, transactionIdStr, sql.Format,
|
||||
)
|
||||
if sql.Error != nil {
|
||||
|
||||
@ -829,6 +829,10 @@ func FormatSqlWithArgs(sql string, args []interface{}) string {
|
||||
if args[index] == nil {
|
||||
return "null"
|
||||
}
|
||||
// Parameters of type Raw do not require special treatment
|
||||
if v, ok := args[index].(Raw); ok {
|
||||
return gconv.String(v)
|
||||
}
|
||||
var (
|
||||
reflectInfo = utils.OriginValueAndKind(args[index])
|
||||
)
|
||||
|
||||
@ -319,32 +319,25 @@ func (m *Model) Scan(pointer interface{}, where ...interface{}) error {
|
||||
|
||||
// ScanList converts `r` to struct slice which contains other complex struct attributes.
|
||||
// Note that the parameter `listPointer` should be type of *[]struct/*[]*struct.
|
||||
// Usage example:
|
||||
//
|
||||
// type Entity struct {
|
||||
// User *EntityUser
|
||||
// UserDetail *EntityUserDetail
|
||||
// UserScores []*EntityUserScores
|
||||
// }
|
||||
// var users []*Entity
|
||||
// or
|
||||
// var users []Entity
|
||||
//
|
||||
// ScanList(&users, "User")
|
||||
// ScanList(&users, "UserDetail", "User", "uid:Uid")
|
||||
// ScanList(&users, "UserScores", "User", "uid:Uid")
|
||||
// The parameters "User"/"UserDetail"/"UserScores" in the example codes specify the target attribute struct
|
||||
// that current result will be bound to.
|
||||
// The "uid" in the example codes is the table field name of the result, and the "Uid" is the relational
|
||||
// struct attribute name. It automatically calculates the HasOne/HasMany relationship with given `relation`
|
||||
// parameter.
|
||||
// See the example or unit testing cases for clear understanding for this function.
|
||||
func (m *Model) ScanList(listPointer interface{}, attributeName string, relation ...string) (err error) {
|
||||
// See Result.ScanList.
|
||||
func (m *Model) ScanList(structSlicePointer interface{}, bindToAttrName string, relationAttrNameAndFields ...string) (err error) {
|
||||
result, err := m.All()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return doScanList(m, result, listPointer, attributeName, relation...)
|
||||
var (
|
||||
relationAttrName string
|
||||
relationFields string
|
||||
)
|
||||
switch len(relationAttrNameAndFields) {
|
||||
case 2:
|
||||
relationAttrName = relationAttrNameAndFields[0]
|
||||
relationFields = relationAttrNameAndFields[1]
|
||||
case 1:
|
||||
relationFields = relationAttrNameAndFields[0]
|
||||
}
|
||||
return doScanList(m, result, structSlicePointer, bindToAttrName, relationAttrName, relationFields)
|
||||
}
|
||||
|
||||
// Count does "SELECT COUNT(x) FROM ..." statement for the model.
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"database/sql"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/structs"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gutil"
|
||||
@ -17,21 +18,61 @@ import (
|
||||
)
|
||||
|
||||
// ScanList converts `r` to struct slice which contains other complex struct attributes.
|
||||
// Note that the parameter `listPointer` should be type of *[]struct/*[]*struct.
|
||||
// Usage example:
|
||||
// Note that the parameter `structSlicePointer` should be type of *[]struct/*[]*struct.
|
||||
//
|
||||
// Usage example 1: Normal attribute struct relation:
|
||||
// type EntityUser struct {
|
||||
// Uid int
|
||||
// Name string
|
||||
// }
|
||||
// type EntityUserDetail struct {
|
||||
// Uid int
|
||||
// Address string
|
||||
// }
|
||||
// type EntityUserScores struct {
|
||||
// Id int
|
||||
// Uid int
|
||||
// Score int
|
||||
// Course string
|
||||
// }
|
||||
// type Entity struct {
|
||||
// User *EntityUser
|
||||
// User *EntityUser
|
||||
// UserDetail *EntityUserDetail
|
||||
// UserScores []*EntityUserScores
|
||||
// UserScores []*EntityUserScores
|
||||
// }
|
||||
// var users []*Entity
|
||||
// or
|
||||
// var users []Entity
|
||||
//
|
||||
// ScanList(&users, "User")
|
||||
// ScanList(&users, "User", "uid")
|
||||
// ScanList(&users, "UserDetail", "User", "uid:Uid")
|
||||
// ScanList(&users, "UserScores", "User", "uid:Uid")
|
||||
// ScanList(&users, "UserScores", "User", "uid")
|
||||
//
|
||||
//
|
||||
// Usage example 2: Embedded attribute struct relation:
|
||||
// type EntityUser struct {
|
||||
// Uid int
|
||||
// Name string
|
||||
// }
|
||||
// type EntityUserDetail struct {
|
||||
// Uid int
|
||||
// Address string
|
||||
// }
|
||||
// type EntityUserScores struct {
|
||||
// Id int
|
||||
// Uid int
|
||||
// Score int
|
||||
// }
|
||||
// type Entity struct {
|
||||
// EntityUser
|
||||
// UserDetail EntityUserDetail
|
||||
// UserScores []EntityUserScores
|
||||
// }
|
||||
//
|
||||
// var users []*Entity
|
||||
// ScanList(&users)
|
||||
// ScanList(&users, "UserDetail", "uid")
|
||||
// ScanList(&users, "UserScores", "uid")
|
||||
//
|
||||
//
|
||||
// The parameters "User/UserDetail/UserScores" in the example codes specify the target attribute struct
|
||||
// that current result will be bound to.
|
||||
@ -42,15 +83,26 @@ import (
|
||||
// given `relation` parameter.
|
||||
//
|
||||
// See the example or unit testing cases for clear understanding for this function.
|
||||
func (r Result) ScanList(listPointer interface{}, bindToAttrName string, relationKV ...string) (err error) {
|
||||
return doScanList(nil, r, listPointer, bindToAttrName, relationKV...)
|
||||
func (r Result) ScanList(structSlicePointer interface{}, bindToAttrName string, relationAttrNameAndFields ...string) (err error) {
|
||||
var (
|
||||
relationAttrName string
|
||||
relationFields string
|
||||
)
|
||||
switch len(relationAttrNameAndFields) {
|
||||
case 2:
|
||||
relationAttrName = relationAttrNameAndFields[0]
|
||||
relationFields = relationAttrNameAndFields[1]
|
||||
case 1:
|
||||
relationFields = relationAttrNameAndFields[0]
|
||||
}
|
||||
return doScanList(nil, r, structSlicePointer, bindToAttrName, relationAttrName, relationFields)
|
||||
}
|
||||
|
||||
// doScanList converts `result` to struct slice which contains other complex struct attributes recursively.
|
||||
// The parameter `model` is used for recursively scanning purpose, which means, it can scans the attribute struct/structs recursively but
|
||||
// it needs the Model for database accessing.
|
||||
// Note that the parameter `listPointer` should be type of *[]struct/*[]*struct.
|
||||
func doScanList(model *Model, result Result, listPointer interface{}, bindToAttrName string, relationKV ...string) (err error) {
|
||||
// The parameter `model` is used for recursively scanning purpose, which means, it can scan the attribute struct/structs recursively,
|
||||
// but it needs the Model for database accessing.
|
||||
// Note that the parameter `structSlicePointer` should be type of *[]struct/*[]*struct.
|
||||
func doScanList(model *Model, result Result, structSlicePointer interface{}, bindToAttrName, relationAttrName, relationFields string) (err error) {
|
||||
if result.IsEmpty() {
|
||||
return nil
|
||||
}
|
||||
@ -59,8 +111,12 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
return gerror.NewCode(gcode.CodeInvalidParameter, `bindToAttrName should not be empty`)
|
||||
}
|
||||
|
||||
if relationAttrName == "." {
|
||||
relationAttrName = ""
|
||||
}
|
||||
|
||||
var (
|
||||
reflectValue = reflect.ValueOf(listPointer)
|
||||
reflectValue = reflect.ValueOf(structSlicePointer)
|
||||
reflectKind = reflectValue.Kind()
|
||||
)
|
||||
if reflectKind == reflect.Interface {
|
||||
@ -70,7 +126,7 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
if reflectKind != reflect.Ptr {
|
||||
return gerror.NewCodef(
|
||||
gcode.CodeInvalidParameter,
|
||||
"listPointer should be type of *[]struct/*[]*struct, but got: %v",
|
||||
"structSlicePointer should be type of *[]struct/*[]*struct, but got: %v",
|
||||
reflectKind,
|
||||
)
|
||||
}
|
||||
@ -79,7 +135,7 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
if reflectKind != reflect.Slice && reflectKind != reflect.Array {
|
||||
return gerror.NewCodef(
|
||||
gcode.CodeInvalidParameter,
|
||||
"listPointer should be type of *[]struct/*[]*struct, but got: %v",
|
||||
"structSlicePointer should be type of *[]struct/*[]*struct, but got: %v",
|
||||
reflectKind,
|
||||
)
|
||||
}
|
||||
@ -99,7 +155,7 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
var (
|
||||
arrayValue reflect.Value // Like: []*Entity
|
||||
arrayItemType reflect.Type // Like: *Entity
|
||||
reflectType = reflect.TypeOf(listPointer)
|
||||
reflectType = reflect.TypeOf(structSlicePointer)
|
||||
)
|
||||
if reflectValue.Len() > 0 {
|
||||
arrayValue = reflectValue
|
||||
@ -112,46 +168,38 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
|
||||
// Relation variables.
|
||||
var (
|
||||
relationKVStr string
|
||||
relationDataMap map[string]Value
|
||||
relationFromAttrName string // Eg: relationKV: User, uid:Uid -> User
|
||||
relationResultFieldName string // Eg: relationKV: uid:Uid -> uid
|
||||
relationBindToSubAttrName string // Eg: relationKV: uid:Uid -> Uid
|
||||
relationDataMap map[string]Value
|
||||
relationFromFieldName string // Eg: relationKV: id:uid -> id
|
||||
relationBindToFieldName string // Eg: relationKV: id:uid -> uid
|
||||
)
|
||||
if len(relationKV) > 0 {
|
||||
if len(relationKV) == 1 {
|
||||
relationKVStr = relationKV[0]
|
||||
} else {
|
||||
relationFromAttrName = relationKV[0]
|
||||
relationKVStr = relationKV[1]
|
||||
}
|
||||
if len(relationFields) > 0 {
|
||||
// The relation key string of table filed name and attribute name
|
||||
// can be joined with char '=' or ':'.
|
||||
array := gstr.SplitAndTrim(relationKVStr, "=")
|
||||
array := gstr.SplitAndTrim(relationFields, "=")
|
||||
if len(array) == 1 {
|
||||
// Compatible with old splitting char ':'.
|
||||
array = gstr.SplitAndTrim(relationKVStr, ":")
|
||||
array = gstr.SplitAndTrim(relationFields, ":")
|
||||
}
|
||||
if len(array) == 1 {
|
||||
// The relation names are the same.
|
||||
array = []string{relationKVStr, relationKVStr}
|
||||
array = []string{relationFields, relationFields}
|
||||
}
|
||||
if len(array) == 2 {
|
||||
// Defined table field to relation attribute name.
|
||||
// Like:
|
||||
// uid:Uid
|
||||
// uid:UserId
|
||||
relationResultFieldName = array[0]
|
||||
relationBindToSubAttrName = array[1]
|
||||
if key, _ := gutil.MapPossibleItemByKey(result[0].Map(), relationResultFieldName); key == "" {
|
||||
relationFromFieldName = array[0]
|
||||
relationBindToFieldName = array[1]
|
||||
if key, _ := gutil.MapPossibleItemByKey(result[0].Map(), relationFromFieldName); key == "" {
|
||||
return gerror.NewCodef(
|
||||
gcode.CodeInvalidParameter,
|
||||
`cannot find possible related table field name "%s" from given relation key "%s"`,
|
||||
relationResultFieldName,
|
||||
relationKVStr,
|
||||
`cannot find possible related table field name "%s" from given relation fields "%s"`,
|
||||
relationFromFieldName,
|
||||
relationFields,
|
||||
)
|
||||
} else {
|
||||
relationResultFieldName = key
|
||||
relationFromFieldName = key
|
||||
}
|
||||
} else {
|
||||
return gerror.NewCode(
|
||||
@ -159,15 +207,15 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
`parameter relationKV should be format of "ResultFieldName:BindToAttrName"`,
|
||||
)
|
||||
}
|
||||
if relationResultFieldName != "" {
|
||||
if relationFromFieldName != "" {
|
||||
// Note that the value might be type of slice.
|
||||
relationDataMap = result.MapKeyValue(relationResultFieldName)
|
||||
relationDataMap = result.MapKeyValue(relationFromFieldName)
|
||||
}
|
||||
if len(relationDataMap) == 0 {
|
||||
return gerror.NewCodef(
|
||||
gcode.CodeInvalidParameter,
|
||||
`cannot find the relation data map, maybe invalid relation given "%v"`,
|
||||
relationKV,
|
||||
`cannot find the relation data map, maybe invalid relation fields given "%v"`,
|
||||
relationFields,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -201,9 +249,9 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
|
||||
// Bind to relation conditions.
|
||||
var (
|
||||
relationFromAttrValue reflect.Value
|
||||
relationFromAttrField reflect.Value
|
||||
relationBindToSubAttrNameChecked bool
|
||||
relationFromAttrValue reflect.Value
|
||||
relationFromAttrField reflect.Value
|
||||
relationBindToFieldNameChecked bool
|
||||
)
|
||||
for i := 0; i < arrayValue.Len(); i++ {
|
||||
arrayElemValue := arrayValue.Index(i)
|
||||
@ -224,9 +272,9 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
// Like: []Entity
|
||||
}
|
||||
bindToAttrValue = arrayElemValue.FieldByName(bindToAttrName)
|
||||
if relationFromAttrName != "" {
|
||||
if relationAttrName != "" {
|
||||
// Attribute value of current slice element.
|
||||
relationFromAttrValue = arrayElemValue.FieldByName(relationFromAttrName)
|
||||
relationFromAttrValue = arrayElemValue.FieldByName(relationAttrName)
|
||||
if relationFromAttrValue.Kind() == reflect.Ptr {
|
||||
relationFromAttrValue = relationFromAttrValue.Elem()
|
||||
}
|
||||
@ -235,36 +283,35 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
relationFromAttrValue = arrayElemValue
|
||||
}
|
||||
if len(relationDataMap) > 0 && !relationFromAttrValue.IsValid() {
|
||||
return gerror.NewCodef(gcode.CodeInvalidParameter, `invalid relation specified: "%v"`, relationKV)
|
||||
return gerror.NewCodef(gcode.CodeInvalidParameter, `invalid relation fields specified: "%v"`, relationFields)
|
||||
}
|
||||
// Check and find possible bind to attribute name.
|
||||
if relationKVStr != "" && !relationBindToSubAttrNameChecked {
|
||||
relationFromAttrField = relationFromAttrValue.FieldByName(relationBindToSubAttrName)
|
||||
if relationFields != "" && !relationBindToFieldNameChecked {
|
||||
relationFromAttrField = relationFromAttrValue.FieldByName(relationBindToFieldName)
|
||||
if !relationFromAttrField.IsValid() {
|
||||
var (
|
||||
relationFromAttrType = relationFromAttrValue.Type()
|
||||
filedMap = make(map[string]interface{})
|
||||
filedMap, _ = structs.FieldMap(structs.FieldMapInput{
|
||||
Pointer: relationFromAttrValue,
|
||||
RecursiveOption: structs.RecursiveOptionEmbeddedNoTag,
|
||||
})
|
||||
)
|
||||
for i := 0; i < relationFromAttrType.NumField(); i++ {
|
||||
filedMap[relationFromAttrType.Field(i).Name] = struct{}{}
|
||||
}
|
||||
if key, _ := gutil.MapPossibleItemByKey(filedMap, relationBindToSubAttrName); key == "" {
|
||||
if key, _ := gutil.MapPossibleItemByKey(gconv.Map(filedMap), relationBindToFieldName); key == "" {
|
||||
return gerror.NewCodef(
|
||||
gcode.CodeInvalidParameter,
|
||||
`cannot find possible related attribute name "%s" from given relation key "%s"`,
|
||||
relationBindToSubAttrName,
|
||||
relationKVStr,
|
||||
`cannot find possible related attribute name "%s" from given relation fields "%s"`,
|
||||
relationBindToFieldName,
|
||||
relationFields,
|
||||
)
|
||||
} else {
|
||||
relationBindToSubAttrName = key
|
||||
relationBindToFieldName = key
|
||||
}
|
||||
}
|
||||
relationBindToSubAttrNameChecked = true
|
||||
relationBindToFieldNameChecked = true
|
||||
}
|
||||
switch bindToAttrKind {
|
||||
case reflect.Array, reflect.Slice:
|
||||
if len(relationDataMap) > 0 {
|
||||
relationFromAttrField = relationFromAttrValue.FieldByName(relationBindToSubAttrName)
|
||||
relationFromAttrField = relationFromAttrValue.FieldByName(relationBindToFieldName)
|
||||
if relationFromAttrField.IsValid() {
|
||||
results := make(Result, 0)
|
||||
for _, v := range relationDataMap[gconv.String(relationFromAttrField.Interface())].Slice() {
|
||||
@ -280,8 +327,8 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// May be the attribute does not exist yet.
|
||||
return gerror.NewCodef(gcode.CodeInvalidParameter, `invalid relation specified: "%v"`, relationKV)
|
||||
// Maybe the attribute does not exist yet.
|
||||
return gerror.NewCodef(gcode.CodeInvalidParameter, `invalid relation fields specified: "%v"`, relationFields)
|
||||
}
|
||||
} else {
|
||||
return gerror.NewCodef(
|
||||
@ -299,7 +346,7 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
element = bindToAttrValue.Elem()
|
||||
}
|
||||
if len(relationDataMap) > 0 {
|
||||
relationFromAttrField = relationFromAttrValue.FieldByName(relationBindToSubAttrName)
|
||||
relationFromAttrField = relationFromAttrValue.FieldByName(relationBindToFieldName)
|
||||
if relationFromAttrField.IsValid() {
|
||||
v := relationDataMap[gconv.String(relationFromAttrField.Interface())]
|
||||
if v == nil {
|
||||
@ -316,8 +363,8 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// May be the attribute does not exist yet.
|
||||
return gerror.NewCodef(gcode.CodeInvalidParameter, `invalid relation specified: "%v"`, relationKV)
|
||||
// Maybe the attribute does not exist yet.
|
||||
return gerror.NewCodef(gcode.CodeInvalidParameter, `invalid relation fields specified: "%v"`, relationFields)
|
||||
}
|
||||
} else {
|
||||
if i >= len(result) {
|
||||
@ -343,7 +390,7 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
|
||||
case reflect.Struct:
|
||||
if len(relationDataMap) > 0 {
|
||||
relationFromAttrField = relationFromAttrValue.FieldByName(relationBindToSubAttrName)
|
||||
relationFromAttrField = relationFromAttrValue.FieldByName(relationBindToFieldName)
|
||||
if relationFromAttrField.IsValid() {
|
||||
relationDataItem := relationDataMap[gconv.String(relationFromAttrField.Interface())]
|
||||
if relationDataItem == nil {
|
||||
@ -360,8 +407,8 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// May be the attribute does not exist yet.
|
||||
return gerror.NewCodef(gcode.CodeInvalidParameter, `invalid relation specified: "%v"`, relationKV)
|
||||
// Maybe the attribute does not exist yet.
|
||||
return gerror.NewCodef(gcode.CodeInvalidParameter, `invalid relation fields specified: "%v"`, relationFields)
|
||||
}
|
||||
} else {
|
||||
if i >= len(result) {
|
||||
@ -388,6 +435,6 @@ func doScanList(model *Model, result Result, listPointer interface{}, bindToAttr
|
||||
return gerror.NewCodef(gcode.CodeInvalidParameter, `unsupported attribute type: %s`, bindToAttrKind.String())
|
||||
}
|
||||
}
|
||||
reflect.ValueOf(listPointer).Elem().Set(arrayValue)
|
||||
reflect.ValueOf(structSlicePointer).Elem().Set(arrayValue)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1553,7 +1553,7 @@ CREATE TABLE %s (
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Table_Relation_EmbeddedStruct(t *testing.T) {
|
||||
func Test_Table_Relation_EmbeddedStruct1(t *testing.T) {
|
||||
var (
|
||||
tableUser = "user_" + gtime.TimestampMicroStr()
|
||||
tableUserDetail = "user_detail_" + gtime.TimestampMicroStr()
|
||||
@ -1670,3 +1670,310 @@ CREATE TABLE %s (
|
||||
t.Assert(scores[24].Address, "address_5")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Table_Relation_EmbeddedStruct2(t *testing.T) {
|
||||
var (
|
||||
tableUser = "user_" + gtime.TimestampMicroStr()
|
||||
tableUserDetail = "user_detail_" + gtime.TimestampMicroStr()
|
||||
tableUserScores = "user_scores_" + gtime.TimestampMicroStr()
|
||||
)
|
||||
if _, err := db.Exec(ctx, fmt.Sprintf(`
|
||||
CREATE TABLE %s (
|
||||
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
name varchar(45) NOT NULL,
|
||||
PRIMARY KEY (uid)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
`, tableUser)); err != nil {
|
||||
gtest.Error(err)
|
||||
}
|
||||
defer dropTable(tableUser)
|
||||
|
||||
if _, err := db.Exec(ctx, fmt.Sprintf(`
|
||||
CREATE TABLE %s (
|
||||
uid int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
address varchar(45) NOT NULL,
|
||||
PRIMARY KEY (uid)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
`, tableUserDetail)); err != nil {
|
||||
gtest.Error(err)
|
||||
}
|
||||
defer dropTable(tableUserDetail)
|
||||
|
||||
if _, err := db.Exec(ctx, fmt.Sprintf(`
|
||||
CREATE TABLE %s (
|
||||
id int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
uid int(10) unsigned NOT NULL,
|
||||
score int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
`, tableUserScores)); err != nil {
|
||||
gtest.Error(err)
|
||||
}
|
||||
defer dropTable(tableUserScores)
|
||||
|
||||
type EntityUser struct {
|
||||
Uid int `json:"uid"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
type EntityUserDetail struct {
|
||||
Uid int `json:"uid"`
|
||||
Address string `json:"address"`
|
||||
}
|
||||
type EntityUserScores struct {
|
||||
Id int `json:"id"`
|
||||
Uid int `json:"uid"`
|
||||
Score int `json:"score"`
|
||||
}
|
||||
type Entity struct {
|
||||
*EntityUser
|
||||
UserDetail *EntityUserDetail
|
||||
UserScores []*EntityUserScores
|
||||
}
|
||||
|
||||
// Initialize the data.
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var err error
|
||||
for i := 1; i <= 5; i++ {
|
||||
// User.
|
||||
_, err = db.Insert(ctx, tableUser, g.Map{
|
||||
"uid": i,
|
||||
"name": fmt.Sprintf(`name_%d`, i),
|
||||
})
|
||||
t.AssertNil(err)
|
||||
// Detail.
|
||||
_, err = db.Insert(ctx, tableUserDetail, g.Map{
|
||||
"uid": i,
|
||||
"address": fmt.Sprintf(`address_%d`, i),
|
||||
})
|
||||
t.AssertNil(err)
|
||||
// Scores.
|
||||
for j := 1; j <= 5; j++ {
|
||||
_, err = db.Insert(ctx, tableUserScores, g.Map{
|
||||
"uid": i,
|
||||
"score": j,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// MapKeyValue.
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
all, err := db.Model(tableUser).Where("uid", g.Slice{3, 4}).Order("uid asc").All()
|
||||
t.AssertNil(err)
|
||||
t.Assert(all.Len(), 2)
|
||||
t.Assert(len(all.MapKeyValue("uid")), 2)
|
||||
t.Assert(all.MapKeyValue("uid")["3"].Map()["uid"], 3)
|
||||
t.Assert(all.MapKeyValue("uid")["4"].Map()["uid"], 4)
|
||||
all, err = db.Model(tableUserScores).Where("uid", g.Slice{3, 4}).Order("id asc").All()
|
||||
t.AssertNil(err)
|
||||
t.Assert(all.Len(), 10)
|
||||
t.Assert(len(all.MapKeyValue("uid")), 2)
|
||||
t.Assert(len(all.MapKeyValue("uid")["3"].Slice()), 5)
|
||||
t.Assert(len(all.MapKeyValue("uid")["4"].Slice()), 5)
|
||||
t.Assert(gconv.Map(all.MapKeyValue("uid")["3"].Slice()[0])["uid"], 3)
|
||||
t.Assert(gconv.Map(all.MapKeyValue("uid")["3"].Slice()[0])["score"], 1)
|
||||
t.Assert(gconv.Map(all.MapKeyValue("uid")["3"].Slice()[4])["uid"], 3)
|
||||
t.Assert(gconv.Map(all.MapKeyValue("uid")["3"].Slice()[4])["score"], 5)
|
||||
})
|
||||
db.SetDebug(true)
|
||||
// Result ScanList with struct elements and pointer attributes.
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var users []Entity
|
||||
// User
|
||||
err := db.Model(tableUser).Where("uid", g.Slice{3, 4}).Order("uid asc").Scan(&users)
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(users), 2)
|
||||
t.Assert(users[0].EntityUser, &EntityUser{3, "name_3"})
|
||||
t.Assert(users[1].EntityUser, &EntityUser{4, "name_4"})
|
||||
// Detail
|
||||
all, err := db.Model(tableUserDetail).Where("uid", gdb.ListItemValues(users, "Uid")).Order("uid asc").All()
|
||||
t.AssertNil(err)
|
||||
err = all.ScanList(&users, "UserDetail", "uid")
|
||||
t.AssertNil(err)
|
||||
t.Assert(users[0].UserDetail, &EntityUserDetail{3, "address_3"})
|
||||
t.Assert(users[1].UserDetail, &EntityUserDetail{4, "address_4"})
|
||||
// Scores
|
||||
all, err = db.Model(tableUserScores).Where("uid", gdb.ListItemValues(users, "Uid")).Order("id asc").All()
|
||||
t.AssertNil(err)
|
||||
err = all.ScanList(&users, "UserScores", "uid")
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(users[0].UserScores), 5)
|
||||
t.Assert(len(users[1].UserScores), 5)
|
||||
t.Assert(users[0].UserScores[0].Uid, 3)
|
||||
t.Assert(users[0].UserScores[0].Score, 1)
|
||||
t.Assert(users[0].UserScores[4].Score, 5)
|
||||
t.Assert(users[1].UserScores[0].Uid, 4)
|
||||
t.Assert(users[1].UserScores[0].Score, 1)
|
||||
t.Assert(users[1].UserScores[4].Score, 5)
|
||||
})
|
||||
|
||||
// Result ScanList with pointer elements and pointer attributes.
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var users []*Entity
|
||||
// User
|
||||
err := db.Model(tableUser).Where("uid", g.Slice{3, 4}).Order("uid asc").Scan(&users)
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(users), 2)
|
||||
t.Assert(users[0].EntityUser, &EntityUser{3, "name_3"})
|
||||
t.Assert(users[1].EntityUser, &EntityUser{4, "name_4"})
|
||||
// Detail
|
||||
all, err := db.Model(tableUserDetail).Where("uid", gdb.ListItemValues(users, "Uid")).Order("uid asc").All()
|
||||
t.AssertNil(err)
|
||||
err = all.ScanList(&users, "UserDetail", "uid")
|
||||
t.AssertNil(err)
|
||||
t.Assert(users[0].UserDetail, &EntityUserDetail{3, "address_3"})
|
||||
t.Assert(users[1].UserDetail, &EntityUserDetail{4, "address_4"})
|
||||
// Scores
|
||||
all, err = db.Model(tableUserScores).Where("uid", gdb.ListItemValues(users, "Uid")).Order("id asc").All()
|
||||
t.AssertNil(err)
|
||||
err = all.ScanList(&users, "UserScores", "uid")
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(users[0].UserScores), 5)
|
||||
t.Assert(len(users[1].UserScores), 5)
|
||||
t.Assert(users[0].UserScores[0].Uid, 3)
|
||||
t.Assert(users[0].UserScores[0].Score, 1)
|
||||
t.Assert(users[0].UserScores[4].Score, 5)
|
||||
t.Assert(users[1].UserScores[0].Uid, 4)
|
||||
t.Assert(users[1].UserScores[0].Score, 1)
|
||||
t.Assert(users[1].UserScores[4].Score, 5)
|
||||
})
|
||||
|
||||
// Result ScanList with struct elements and struct attributes.
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type EntityUser struct {
|
||||
Uid int `json:"uid"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
type EntityUserDetail struct {
|
||||
Uid int `json:"uid"`
|
||||
Address string `json:"address"`
|
||||
}
|
||||
type EntityUserScores struct {
|
||||
Id int `json:"id"`
|
||||
Uid int `json:"uid"`
|
||||
Score int `json:"score"`
|
||||
}
|
||||
type Entity struct {
|
||||
EntityUser
|
||||
UserDetail EntityUserDetail
|
||||
UserScores []EntityUserScores
|
||||
}
|
||||
var users []Entity
|
||||
// User
|
||||
err := db.Model(tableUser).Where("uid", g.Slice{3, 4}).Order("uid asc").Scan(&users)
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(users), 2)
|
||||
t.Assert(users[0].EntityUser, &EntityUser{3, "name_3"})
|
||||
t.Assert(users[1].EntityUser, &EntityUser{4, "name_4"})
|
||||
// Detail
|
||||
all, err := db.Model(tableUserDetail).Where("uid", gdb.ListItemValues(users, "Uid")).Order("uid asc").All()
|
||||
t.AssertNil(err)
|
||||
err = all.ScanList(&users, "UserDetail", "uid")
|
||||
t.AssertNil(err)
|
||||
t.Assert(users[0].UserDetail, &EntityUserDetail{3, "address_3"})
|
||||
t.Assert(users[1].UserDetail, &EntityUserDetail{4, "address_4"})
|
||||
// Scores
|
||||
all, err = db.Model(tableUserScores).Where("uid", gdb.ListItemValues(users, "Uid")).Order("id asc").All()
|
||||
t.AssertNil(err)
|
||||
err = all.ScanList(&users, "UserScores", "uid")
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(users[0].UserScores), 5)
|
||||
t.Assert(len(users[1].UserScores), 5)
|
||||
t.Assert(users[0].UserScores[0].Uid, 3)
|
||||
t.Assert(users[0].UserScores[0].Score, 1)
|
||||
t.Assert(users[0].UserScores[4].Score, 5)
|
||||
t.Assert(users[1].UserScores[0].Uid, 4)
|
||||
t.Assert(users[1].UserScores[0].Score, 1)
|
||||
t.Assert(users[1].UserScores[4].Score, 5)
|
||||
})
|
||||
|
||||
// Result ScanList with pointer elements and struct attributes.
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type EntityUser struct {
|
||||
Uid int `json:"uid"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
type EntityUserDetail struct {
|
||||
Uid int `json:"uid"`
|
||||
Address string `json:"address"`
|
||||
}
|
||||
type EntityUserScores struct {
|
||||
Id int `json:"id"`
|
||||
Uid int `json:"uid"`
|
||||
Score int `json:"score"`
|
||||
}
|
||||
type Entity struct {
|
||||
EntityUser
|
||||
UserDetail EntityUserDetail
|
||||
UserScores []EntityUserScores
|
||||
}
|
||||
var users []*Entity
|
||||
|
||||
// User
|
||||
err := db.Model(tableUser).Where("uid", g.Slice{3, 4}).Order("uid asc").Scan(&users)
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(users), 2)
|
||||
t.Assert(users[0].EntityUser, &EntityUser{3, "name_3"})
|
||||
t.Assert(users[1].EntityUser, &EntityUser{4, "name_4"})
|
||||
// Detail
|
||||
all, err := db.Model(tableUserDetail).Where("uid", gdb.ListItemValues(users, "Uid")).Order("uid asc").All()
|
||||
t.AssertNil(err)
|
||||
err = all.ScanList(&users, "UserDetail", "uid")
|
||||
t.AssertNil(err)
|
||||
t.Assert(users[0].UserDetail, &EntityUserDetail{3, "address_3"})
|
||||
t.Assert(users[1].UserDetail, &EntityUserDetail{4, "address_4"})
|
||||
// Scores
|
||||
all, err = db.Model(tableUserScores).Where("uid", gdb.ListItemValues(users, "Uid")).Order("id asc").All()
|
||||
t.AssertNil(err)
|
||||
err = all.ScanList(&users, "UserScores", "uid")
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(users[0].UserScores), 5)
|
||||
t.Assert(len(users[1].UserScores), 5)
|
||||
t.Assert(users[0].UserScores[0].Uid, 3)
|
||||
t.Assert(users[0].UserScores[0].Score, 1)
|
||||
t.Assert(users[0].UserScores[4].Score, 5)
|
||||
t.Assert(users[1].UserScores[0].Uid, 4)
|
||||
t.Assert(users[1].UserScores[0].Score, 1)
|
||||
t.Assert(users[1].UserScores[4].Score, 5)
|
||||
})
|
||||
|
||||
// Model ScanList with pointer elements and pointer attributes.
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var users []*Entity
|
||||
// User
|
||||
err := db.Model(tableUser).
|
||||
Where("uid", g.Slice{3, 4}).
|
||||
Order("uid asc").
|
||||
Scan(&users)
|
||||
t.AssertNil(err)
|
||||
// Detail
|
||||
err = db.Model(tableUserDetail).
|
||||
Where("uid", gdb.ListItemValues(users, "Uid")).
|
||||
Order("uid asc").
|
||||
ScanList(&users, "UserDetail", "uid:Uid")
|
||||
t.AssertNil(err)
|
||||
// Scores
|
||||
err = db.Model(tableUserScores).
|
||||
Where("uid", gdb.ListItemValues(users, "Uid")).
|
||||
Order("id asc").
|
||||
ScanList(&users, "UserScores", "uid:Uid")
|
||||
t.AssertNil(err)
|
||||
|
||||
t.Assert(len(users), 2)
|
||||
t.Assert(users[0].EntityUser, &EntityUser{3, "name_3"})
|
||||
t.Assert(users[1].EntityUser, &EntityUser{4, "name_4"})
|
||||
|
||||
t.Assert(users[0].UserDetail, &EntityUserDetail{3, "address_3"})
|
||||
t.Assert(users[1].UserDetail, &EntityUserDetail{4, "address_4"})
|
||||
|
||||
t.Assert(len(users[0].UserScores), 5)
|
||||
t.Assert(len(users[1].UserScores), 5)
|
||||
t.Assert(users[0].UserScores[0].Uid, 3)
|
||||
t.Assert(users[0].UserScores[0].Score, 1)
|
||||
t.Assert(users[0].UserScores[4].Score, 5)
|
||||
t.Assert(users[1].UserScores[0].Uid, 4)
|
||||
t.Assert(users[1].UserScores[0].Score, 1)
|
||||
t.Assert(users[1].UserScores[4].Score, 5)
|
||||
})
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ func Decode(data []byte) (res map[string]interface{}, err error) {
|
||||
|
||||
if strings.Contains(lineStr, "=") && haveSection {
|
||||
values := strings.Split(lineStr, "=")
|
||||
fieldMap[strings.TrimSpace(values[0])] = strings.TrimSpace(strings.Join(values[1:], ""))
|
||||
fieldMap[strings.TrimSpace(values[0])] = strings.TrimSpace(strings.Join(values[1:], "="))
|
||||
res[section] = fieldMap
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ aa=bb
|
||||
ip = 127.0.0.1
|
||||
port=9001
|
||||
enable=true
|
||||
command=/bin/echo "gf=GoFrame"
|
||||
|
||||
[DBINFO]
|
||||
type=mysql
|
||||
@ -40,6 +41,7 @@ func TestDecode(t *testing.T) {
|
||||
}
|
||||
t.Assert(res["addr"].(map[string]interface{})["ip"], "127.0.0.1")
|
||||
t.Assert(res["addr"].(map[string]interface{})["port"], "9001")
|
||||
t.Assert(res["addr"].(map[string]interface{})["command"], `/bin/echo "gf=GoFrame"`)
|
||||
t.Assert(res["DBINFO"].(map[string]interface{})["user"], "root")
|
||||
t.Assert(res["DBINFO"].(map[string]interface{})["type"], "mysql")
|
||||
t.Assert(res["键"].(map[string]interface{})["呵呵"], "值")
|
||||
|
||||
501
os/gcache/gcache_z_example_cache_test.go
Normal file
501
os/gcache/gcache_z_example_cache_test.go
Normal file
@ -0,0 +1,501 @@
|
||||
package gcache_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gcache"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ExampleNew() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly.
|
||||
c := gcache.New()
|
||||
|
||||
// Set cache without expiration
|
||||
c.Set(ctx, "k1", "v1", 0)
|
||||
|
||||
// Get cache
|
||||
v, _ := c.Get(ctx, "k1")
|
||||
fmt.Println(v)
|
||||
|
||||
// Get cache size
|
||||
n, _ := c.Size(ctx)
|
||||
fmt.Println(n)
|
||||
|
||||
// Does the specified key name exist in the cache
|
||||
b, _ := c.Contains(ctx, "k1")
|
||||
fmt.Println(b)
|
||||
|
||||
// Delete and return the deleted key value
|
||||
fmt.Println(c.Remove(ctx, "k1"))
|
||||
|
||||
// Close the cache object and let the GC reclaim resources
|
||||
|
||||
c.Close(ctx)
|
||||
|
||||
// Output:
|
||||
// v1
|
||||
// 1
|
||||
// true
|
||||
// v1 <nil>
|
||||
}
|
||||
|
||||
func ExampleCache_Set() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// Set cache without expiration
|
||||
c.Set(ctx, "k1", g.Slice{1, 2, 3, 4, 5, 6, 7, 8, 9}, 0)
|
||||
|
||||
// Get cache
|
||||
fmt.Println(c.Get(ctx, "k1"))
|
||||
|
||||
// Output:
|
||||
// [1,2,3,4,5,6,7,8,9] <nil>
|
||||
}
|
||||
|
||||
func ExampleCache_SetAdapters() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// SetAdapter changes the adapter for this cache. Be very note that, this setting function is not concurrent-safe,
|
||||
// which means you should not call this setting function concurrently in multiple goroutines.
|
||||
adapter := gcache.New()
|
||||
c.SetAdapter(adapter)
|
||||
|
||||
// Set cache
|
||||
c.Set(ctx, "k1", g.Slice{1, 2, 3, 4, 5, 6, 7, 8, 9}, 0)
|
||||
|
||||
// Reverse makes array with elements in reverse order.
|
||||
fmt.Println(c.Get(ctx, "k1"))
|
||||
|
||||
// Output:
|
||||
// [1,2,3,4,5,6,7,8,9] <nil>
|
||||
}
|
||||
|
||||
func ExampleCache_SetIfNotExist() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// Write when the key name does not exist, and set the expiration time to 1000 milliseconds
|
||||
k1, err := c.SetIfNotExist(ctx, "k1", "v1", 1000*time.Millisecond)
|
||||
fmt.Println(k1, err)
|
||||
|
||||
// Returns false when the key name already exists
|
||||
k2, err := c.SetIfNotExist(ctx, "k1", "v2", 1000*time.Millisecond)
|
||||
fmt.Println(k2, err)
|
||||
|
||||
// Print the current list of key values
|
||||
keys1, _ := c.Keys(ctx)
|
||||
fmt.Println(keys1)
|
||||
|
||||
// It does not expire if `duration` == 0. It deletes the `key` if `duration` < 0 or given `value` is nil.
|
||||
c.SetIfNotExist(ctx, "k1", 0, -10000)
|
||||
|
||||
// Wait 1 second for K1: V1 to expire automatically
|
||||
time.Sleep(1200 * time.Millisecond)
|
||||
|
||||
// Print the current key value pair again and find that K1: V1 has expired
|
||||
keys2, _ := c.Keys(ctx)
|
||||
fmt.Println(keys2)
|
||||
|
||||
// Output:
|
||||
// true <nil>
|
||||
// false <nil>
|
||||
// [k1]
|
||||
// [<nil>]
|
||||
}
|
||||
|
||||
func ExampleCache_SetMap() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// map[interface{}]interface{}
|
||||
data := g.MapAnyAny{
|
||||
"k1": "v1",
|
||||
"k2": "v2",
|
||||
"k3": "v3",
|
||||
}
|
||||
|
||||
// Sets batch sets cache with key-value pairs by `data`, which is expired after `duration`.
|
||||
// It does not expire if `duration` == 0. It deletes the keys of `data` if `duration` < 0 or given `value` is nil.
|
||||
c.SetMap(ctx, data, 1000*time.Millisecond)
|
||||
|
||||
// Gets the specified key value
|
||||
v1, _ := c.Get(ctx, "k1")
|
||||
v2, _ := c.Get(ctx, "k2")
|
||||
v3, _ := c.Get(ctx, "k3")
|
||||
|
||||
fmt.Println(v1, v2, v3)
|
||||
|
||||
// Output:
|
||||
// v1 v2 v3
|
||||
}
|
||||
|
||||
func ExampleCache_Size() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// Add 10 elements without expiration
|
||||
for i := 0; i < 10; i++ {
|
||||
c.Set(ctx, i, i, 0)
|
||||
}
|
||||
|
||||
// Size returns the number of items in the cache.
|
||||
n, _ := c.Size(ctx)
|
||||
fmt.Println(n)
|
||||
|
||||
// Output:
|
||||
// 10
|
||||
}
|
||||
|
||||
func ExampleCache_Update() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// Sets batch sets cache with key-value pairs by `data`, which is expired after `duration`.
|
||||
// It does not expire if `duration` == 0. It deletes the keys of `data` if `duration` < 0 or given `value` is nil.
|
||||
c.SetMap(ctx, g.MapAnyAny{"k1": "v1", "k2": "v2", "k3": "v3"}, 0)
|
||||
|
||||
// Print the current key value pair
|
||||
k1, _ := c.Get(ctx, "k1")
|
||||
fmt.Println(k1)
|
||||
k2, _ := c.Get(ctx, "k2")
|
||||
fmt.Println(k2)
|
||||
k3, _ := c.Get(ctx, "k3")
|
||||
fmt.Println(k3)
|
||||
|
||||
// Update updates the value of `key` without changing its expiration and returns the old value.
|
||||
re, exist, _ := c.Update(ctx, "k1", "v11")
|
||||
fmt.Println(re, exist)
|
||||
|
||||
// The returned value `exist` is false if the `key` does not exist in the cache.
|
||||
// It does nothing if `key` does not exist in the cache.
|
||||
re1, exist1, _ := c.Update(ctx, "k4", "v44")
|
||||
fmt.Println(re1, exist1)
|
||||
|
||||
kup1, _ := c.Get(ctx, "k1")
|
||||
fmt.Println(kup1)
|
||||
kup2, _ := c.Get(ctx, "k2")
|
||||
fmt.Println(kup2)
|
||||
kup3, _ := c.Get(ctx, "k3")
|
||||
fmt.Println(kup3)
|
||||
|
||||
// Output:
|
||||
// v1
|
||||
// v2
|
||||
// v3
|
||||
// v1 true
|
||||
// false
|
||||
// v11
|
||||
// v2
|
||||
// v3
|
||||
}
|
||||
|
||||
func ExampleCache_UpdateExpire() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
c.Set(ctx, "k1", "v1", 1000*time.Millisecond)
|
||||
expire, _ := c.GetExpire(ctx, "k1")
|
||||
fmt.Println(expire)
|
||||
|
||||
// UpdateExpire updates the expiration of `key` and returns the old expiration duration value.
|
||||
// It returns -1 and does nothing if the `key` does not exist in the cache.
|
||||
c.UpdateExpire(ctx, "k1", 500*time.Millisecond)
|
||||
|
||||
expire1, _ := c.GetExpire(ctx, "k1")
|
||||
fmt.Println(expire1)
|
||||
|
||||
// Output:
|
||||
// 1s
|
||||
// 500ms
|
||||
}
|
||||
|
||||
func ExampleCache_Values() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// Write value
|
||||
c.Set(ctx, "k1", g.Map{"k1": "v1", "k2": "v2"}, 0)
|
||||
// c.Set(ctx, "k2", "Here is Value2", 0)
|
||||
// c.Set(ctx, "k3", 111, 0)
|
||||
|
||||
// Values returns all values in the cache as slice.
|
||||
data, _ := c.Values(ctx)
|
||||
fmt.Println(data)
|
||||
|
||||
// May Output:
|
||||
// [map[k1:v1 k2:v2]]
|
||||
}
|
||||
|
||||
func ExampleCache_Close() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// Set Cache
|
||||
c.Set(ctx, "k1", "v", 0)
|
||||
data, _ := c.Get(ctx, "k1")
|
||||
fmt.Println(data)
|
||||
|
||||
// Close closes the cache if necessary.
|
||||
c.Close(ctx)
|
||||
|
||||
data1, _ := c.Get(ctx, "k1")
|
||||
|
||||
fmt.Println(data1)
|
||||
|
||||
// Output:
|
||||
// v
|
||||
// v
|
||||
|
||||
}
|
||||
|
||||
func ExampleCache_Contains() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// Set Cache
|
||||
c.Set(ctx, "k", "v", 0)
|
||||
|
||||
// Contains returns true if `key` exists in the cache, or else returns false.
|
||||
// return true
|
||||
data, _ := c.Contains(ctx, "k")
|
||||
fmt.Println(data)
|
||||
|
||||
// return false
|
||||
data1, _ := c.Contains(ctx, "k1")
|
||||
fmt.Println(data1)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
|
||||
}
|
||||
|
||||
func ExampleCache_Data() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
c.SetMap(ctx, g.MapAnyAny{"k1": "v1", "k2": "v2"}, 0)
|
||||
c.Set(ctx, "k5", "v5", 0)
|
||||
|
||||
// Get retrieves and returns the associated value of given `key`.
|
||||
// It returns nil if it does not exist, its value is nil or it's expired.
|
||||
data, _ := c.Get(ctx, "k1")
|
||||
fmt.Println(data)
|
||||
|
||||
data1, _ := c.Get(ctx, "k2")
|
||||
fmt.Println(data1)
|
||||
|
||||
data2, _ := c.Get(ctx, "k5")
|
||||
fmt.Println(data2)
|
||||
|
||||
// Output:
|
||||
// v1
|
||||
// v2
|
||||
// v5
|
||||
}
|
||||
|
||||
func ExampleCache_Get() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// Set Cache Object
|
||||
c.Set(ctx, "k1", "v1", 0)
|
||||
|
||||
// Get retrieves and returns the associated value of given `key`.
|
||||
// It returns nil if it does not exist, its value is nil or it's expired.
|
||||
data, _ := c.Get(ctx, "k1")
|
||||
fmt.Println(data)
|
||||
|
||||
// Output:
|
||||
// v1
|
||||
}
|
||||
|
||||
func ExampleCache_GetExpire() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// Set cache without expiration
|
||||
c.Set(ctx, "k", "v", 10000*time.Millisecond)
|
||||
|
||||
// GetExpire retrieves and returns the expiration of `key` in the cache.
|
||||
// It returns 0 if the `key` does not expire. It returns -1 if the `key` does not exist in the cache.
|
||||
expire, _ := c.GetExpire(ctx, "k")
|
||||
fmt.Println(expire)
|
||||
|
||||
// Output:
|
||||
// 10s
|
||||
}
|
||||
|
||||
func ExampleCache_GetOrSet() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// GetOrSet retrieves and returns the value of `key`, or sets `key`-`value` pair and returns `value`
|
||||
// if `key` does not exist in the cache.
|
||||
data, _ := c.GetOrSet(ctx, "k", "v", 10000*time.Millisecond)
|
||||
fmt.Println(data)
|
||||
|
||||
data1, _ := c.Get(ctx, "k")
|
||||
fmt.Println(data1)
|
||||
|
||||
// Output:
|
||||
// v
|
||||
// v
|
||||
|
||||
}
|
||||
|
||||
func ExampleCache_GetOrSetFunc() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// GetOrSetFunc retrieves and returns the value of `key`, or sets `key` with result of function `f`
|
||||
// and returns its result if `key` does not exist in the cache.
|
||||
c.GetOrSetFunc(ctx, 1, func() (interface{}, error) {
|
||||
return 111, nil
|
||||
}, 10000*time.Millisecond)
|
||||
v, _ := c.Get(ctx, 1)
|
||||
fmt.Println(v)
|
||||
|
||||
c.GetOrSetFunc(ctx, 2, func() (interface{}, error) {
|
||||
return nil, nil
|
||||
}, 10000*time.Millisecond)
|
||||
v1, _ := c.Get(ctx, 2)
|
||||
fmt.Println(v1)
|
||||
|
||||
// Output:
|
||||
// 111
|
||||
//
|
||||
}
|
||||
|
||||
func ExampleCache_GetOrSetFuncLock() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
// Modify locking Note that the function `f` should be executed within writing mutex lock for concurrent safety purpose.
|
||||
c.GetOrSetFuncLock(ctx, 1, func() (interface{}, error) {
|
||||
return 11, nil
|
||||
}, 0)
|
||||
v, _ := c.Get(ctx, 1)
|
||||
fmt.Println(v)
|
||||
|
||||
// Modification failed
|
||||
c.GetOrSetFuncLock(ctx, 1, func() (interface{}, error) {
|
||||
return 111, nil
|
||||
}, 0)
|
||||
v, _ = c.Get(ctx, 1)
|
||||
fmt.Println(v)
|
||||
|
||||
c.Remove(ctx, g.Slice{1, 2, 3}...)
|
||||
|
||||
// Modify locking
|
||||
c.GetOrSetFuncLock(ctx, 1, func() (interface{}, error) {
|
||||
return 111, nil
|
||||
}, 0)
|
||||
v, _ = c.Get(ctx, 1)
|
||||
fmt.Println(v)
|
||||
|
||||
// Modification failed
|
||||
c.GetOrSetFuncLock(ctx, 1, func() (interface{}, error) {
|
||||
return 11, nil
|
||||
}, 0)
|
||||
v, _ = c.Get(ctx, 1)
|
||||
fmt.Println(v)
|
||||
|
||||
// Output:
|
||||
// 11
|
||||
// 11
|
||||
// 111
|
||||
// 111
|
||||
}
|
||||
|
||||
func ExampleCache_Keys() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
c.SetMap(ctx, g.MapAnyAny{"k1": "v1"}, 0)
|
||||
|
||||
// Print the current list of key values
|
||||
keys1, _ := c.Keys(ctx)
|
||||
fmt.Println(keys1)
|
||||
|
||||
// Output:
|
||||
// [k1]
|
||||
|
||||
}
|
||||
|
||||
func ExampleCache_Remove() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
c.SetMap(ctx, g.MapAnyAny{"k1": "v1", "k2": "v2"}, 0)
|
||||
|
||||
// Remove deletes one or more keys from cache, and returns its value.
|
||||
// If multiple keys are given, it returns the value of the last deleted item.
|
||||
c.Remove(ctx, "k1")
|
||||
|
||||
data, _ := c.Data(ctx)
|
||||
fmt.Println(data)
|
||||
|
||||
// Output:
|
||||
// map[k2:v2]
|
||||
}
|
||||
|
||||
func ExampleCache_Removes() {
|
||||
|
||||
// Create a cache object,
|
||||
// Of course, you can also easily use the gcache package method directly
|
||||
c := gcache.New()
|
||||
|
||||
c.SetMap(ctx, g.MapAnyAny{"k1": "v1", "k2": "v2", "k3": "v3", "k4": "v4"}, 0)
|
||||
|
||||
// Remove deletes one or more keys from cache, and returns its value.
|
||||
// If multiple keys are given, it returns the value of the last deleted item.
|
||||
c.Removes(ctx, g.Slice{"k1", "k2", "k3"})
|
||||
|
||||
data, _ := c.Data(ctx)
|
||||
fmt.Println(data)
|
||||
|
||||
// Output:
|
||||
// map[k4:v4]
|
||||
}
|
||||
@ -202,7 +202,7 @@ func (l *Logger) print(ctx context.Context, level int, values ...interface{}) {
|
||||
if len(input.Content) > 0 {
|
||||
if input.Content[len(input.Content)-1] == '\n' {
|
||||
// Remove one blank line(\n\n).
|
||||
if tempStr[0] == '\n' {
|
||||
if len(tempStr) > 0 && tempStr[0] == '\n' {
|
||||
input.Content += tempStr[1:]
|
||||
} else {
|
||||
input.Content += tempStr
|
||||
|
||||
280
text/gregex/gregex_z_example_test.go
Normal file
280
text/gregex/gregex_z_example_test.go
Normal file
@ -0,0 +1,280 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). 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 gregex_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ExampleIsMatch() {
|
||||
patternStr := `\d+`
|
||||
g.Dump(gregex.IsMatch(patternStr, []byte("hello 2022! hello gf!")))
|
||||
g.Dump(gregex.IsMatch(patternStr, nil))
|
||||
g.Dump(gregex.IsMatch(patternStr, []byte("hello gf!")))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleIsMatchString() {
|
||||
patternStr := `\d+`
|
||||
g.Dump(gregex.IsMatchString(patternStr, "hello 2022! hello gf!"))
|
||||
g.Dump(gregex.IsMatchString(patternStr, "hello gf!"))
|
||||
g.Dump(gregex.IsMatchString(patternStr, ""))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleMatch() {
|
||||
patternStr := `(\w+)=(\w+)`
|
||||
matchStr := "https://goframe.org/pages/viewpage.action?pageId=1114219&searchId=8QC5D1D2E!"
|
||||
// This method looks for the first match index
|
||||
result, err := gregex.Match(patternStr, []byte(matchStr))
|
||||
g.Dump(result)
|
||||
g.Dump(err)
|
||||
|
||||
// Output:
|
||||
// [
|
||||
// "pageId=1114219",
|
||||
// "pageId",
|
||||
// "1114219",
|
||||
// ]
|
||||
// <nil>
|
||||
}
|
||||
|
||||
func ExampleMatchString() {
|
||||
patternStr := `(\w+)=(\w+)`
|
||||
matchStr := "https://goframe.org/pages/viewpage.action?pageId=1114219&searchId=8QC5D1D2E!"
|
||||
// This method looks for the first match index
|
||||
result, err := gregex.MatchString(patternStr, matchStr)
|
||||
g.Dump(result)
|
||||
g.Dump(err)
|
||||
|
||||
// Output:
|
||||
// [
|
||||
// "pageId=1114219",
|
||||
// "pageId",
|
||||
// "1114219",
|
||||
// ]
|
||||
// <nil>
|
||||
}
|
||||
|
||||
func ExampleMatchAll() {
|
||||
patternStr := `(\w+)=(\w+)`
|
||||
matchStr := "https://goframe.org/pages/viewpage.action?pageId=1114219&searchId=8QC5D1D2E!"
|
||||
result, err := gregex.MatchAll(patternStr, []byte(matchStr))
|
||||
g.Dump(result)
|
||||
g.Dump(err)
|
||||
|
||||
// Output:
|
||||
// [
|
||||
// [
|
||||
// "pageId=1114219",
|
||||
// "pageId",
|
||||
// "1114219",
|
||||
// ],
|
||||
// [
|
||||
// "searchId=8QC5D1D2E",
|
||||
// "searchId",
|
||||
// "8QC5D1D2E",
|
||||
// ],
|
||||
// ]
|
||||
// <nil>
|
||||
}
|
||||
|
||||
func ExampleMatchAllString() {
|
||||
patternStr := `(\w+)=(\w+)`
|
||||
matchStr := "https://goframe.org/pages/viewpage.action?pageId=1114219&searchId=8QC5D1D2E!"
|
||||
result, err := gregex.MatchAllString(patternStr, matchStr)
|
||||
g.Dump(result)
|
||||
g.Dump(err)
|
||||
|
||||
// Output:
|
||||
// [
|
||||
// [
|
||||
// "pageId=1114219",
|
||||
// "pageId",
|
||||
// "1114219",
|
||||
// ],
|
||||
// [
|
||||
// "searchId=8QC5D1D2E",
|
||||
// "searchId",
|
||||
// "8QC5D1D2E",
|
||||
// ],
|
||||
// ]
|
||||
// <nil>
|
||||
}
|
||||
|
||||
func ExampleQuote() {
|
||||
result := gregex.Quote(`[1-9]\d+`)
|
||||
g.Dump(result)
|
||||
|
||||
// Output:
|
||||
// "\[1-9\]\\d\+"
|
||||
}
|
||||
|
||||
func ExampleReplace() {
|
||||
var (
|
||||
patternStr = `\d+`
|
||||
str = "hello gf 2020!"
|
||||
repStr = "2021"
|
||||
result, err = gregex.Replace(patternStr, []byte(repStr), []byte(str))
|
||||
)
|
||||
g.Dump(err)
|
||||
g.Dump(result)
|
||||
|
||||
// Output:
|
||||
// <nil>
|
||||
// "hello gf 2021!"
|
||||
}
|
||||
|
||||
func ExampleReplaceFunc() {
|
||||
// In contrast to [ExampleReplaceFunc]
|
||||
// the result contains the `pattern' of all subpattern that use the matching function
|
||||
result, err := gregex.ReplaceFuncMatch(`(\d+)~(\d+)`, []byte("hello gf 2018~2020!"), func(match [][]byte) []byte {
|
||||
g.Dump(match)
|
||||
match[2] = []byte("2021")
|
||||
return bytes.Join(match[1:], []byte("~"))
|
||||
})
|
||||
g.Dump(result)
|
||||
g.Dump(err)
|
||||
|
||||
// Output:
|
||||
// [
|
||||
// "2018~2020",
|
||||
// "2018",
|
||||
// "2020",
|
||||
// ]
|
||||
// "hello gf 2018~2021!"
|
||||
// <nil>
|
||||
}
|
||||
|
||||
func ExampleReplaceFuncMatch() {
|
||||
var (
|
||||
patternStr = `(\d+)~(\d+)`
|
||||
str = "hello gf 2018~2020!"
|
||||
)
|
||||
// In contrast to [ExampleReplaceFunc]
|
||||
// the result contains the `pattern' of all subpatterns that use the matching function
|
||||
result, err := gregex.ReplaceFuncMatch(patternStr, []byte(str), func(match [][]byte) []byte {
|
||||
g.Dump(match)
|
||||
match[2] = []byte("2021")
|
||||
return bytes.Join(match[1:], []byte("-"))
|
||||
})
|
||||
g.Dump(result)
|
||||
g.Dump(err)
|
||||
|
||||
// Output:
|
||||
// [
|
||||
// "2018~2020",
|
||||
// "2018",
|
||||
// "2020",
|
||||
// ]
|
||||
// "hello gf 2018-2021!"
|
||||
// <nil>
|
||||
}
|
||||
|
||||
func ExampleReplaceString() {
|
||||
patternStr := `\d+`
|
||||
str := "hello gf 2020!"
|
||||
replaceStr := "2021"
|
||||
result, err := gregex.ReplaceString(patternStr, replaceStr, str)
|
||||
|
||||
g.Dump(result)
|
||||
g.Dump(err)
|
||||
|
||||
// Output:
|
||||
// "hello gf 2021!"
|
||||
// <nil>
|
||||
}
|
||||
|
||||
func ExampleReplaceStringFunc() {
|
||||
replaceStrMap := map[string]string{
|
||||
"2020": "2021",
|
||||
}
|
||||
// When the regular statement can match multiple results
|
||||
// func can be used to further control the value that needs to be modified
|
||||
result, err := gregex.ReplaceStringFunc(`\d+`, `hello gf 2018~2020!`, func(b string) string {
|
||||
g.Dump(b)
|
||||
if replaceStr, ok := replaceStrMap[b]; ok {
|
||||
return replaceStr
|
||||
}
|
||||
return b
|
||||
})
|
||||
g.Dump(result)
|
||||
g.Dump(err)
|
||||
|
||||
result, err = gregex.ReplaceStringFunc(`[a-z]*`, "gf@goframe.org", strings.ToUpper)
|
||||
g.Dump(result)
|
||||
g.Dump(err)
|
||||
|
||||
// Output:
|
||||
// "2018"
|
||||
// "2020"
|
||||
// "hello gf 2018~2021!"
|
||||
// <nil>
|
||||
// "GF@GOFRAME.ORG"
|
||||
// <nil>
|
||||
}
|
||||
|
||||
func ExampleReplaceStringFuncMatch() {
|
||||
var (
|
||||
patternStr = `([A-Z])\w+`
|
||||
str = "hello Golang 2018~2021!"
|
||||
)
|
||||
// In contrast to [ExampleReplaceFunc]
|
||||
// the result contains the `pattern' of all subpatterns that use the matching function
|
||||
result, err := gregex.ReplaceStringFuncMatch(patternStr, str, func(match []string) string {
|
||||
g.Dump(match)
|
||||
match[0] = "Gf"
|
||||
return match[0]
|
||||
})
|
||||
g.Dump(result)
|
||||
g.Dump(err)
|
||||
|
||||
// Output:
|
||||
// [
|
||||
// "Golang",
|
||||
// "G",
|
||||
// ]
|
||||
// "hello Gf 2018~2021!"
|
||||
// <nil>
|
||||
}
|
||||
|
||||
func ExampleSplit() {
|
||||
patternStr := `\d+`
|
||||
str := "hello2020gf"
|
||||
result := gregex.Split(patternStr, str)
|
||||
g.Dump(result)
|
||||
|
||||
// Output:
|
||||
// [
|
||||
// "hello",
|
||||
// "gf",
|
||||
// ]
|
||||
}
|
||||
|
||||
func ExampleValidate() {
|
||||
// Valid match statement
|
||||
g.Dump(gregex.Validate(`\d+`))
|
||||
// Mismatched statement
|
||||
g.Dump(gregex.Validate(`[a-9]\d+`))
|
||||
|
||||
// Output:
|
||||
// <nil>
|
||||
// {
|
||||
// Code: "invalid character class range",
|
||||
// Expr: "a-9",
|
||||
// }
|
||||
}
|
||||
@ -20,7 +20,7 @@ import (
|
||||
|
||||
// Struct maps the params key-value pairs to the corresponding struct object's attributes.
|
||||
// The third parameter `mapping` is unnecessary, indicating the mapping rules between the
|
||||
// custom key name and the attribute name(case sensitive).
|
||||
// custom key name and the attribute name(case-sensitive).
|
||||
//
|
||||
// Note:
|
||||
// 1. The `params` can be any type of map/struct, usually a map.
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"github.com/gogf/gf/v2/internal/structs"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ExportOption specifies the behavior of function Export.
|
||||
@ -56,12 +57,17 @@ type doExportOption struct {
|
||||
}
|
||||
|
||||
func doExport(value interface{}, indent string, buffer *bytes.Buffer, option doExportOption) {
|
||||
if value == nil {
|
||||
buffer.WriteString(`<nil>`)
|
||||
return
|
||||
}
|
||||
var (
|
||||
reflectValue = reflect.ValueOf(value)
|
||||
reflectKind = reflectValue.Kind()
|
||||
reflectTypeName = reflectValue.Type().String()
|
||||
reflectTypeName = reflect.TypeOf(value).String()
|
||||
newIndent = indent + dumpIndent
|
||||
)
|
||||
reflectTypeName = strings.ReplaceAll(reflectTypeName, `[]uint8`, `[]byte`)
|
||||
if option.WithoutType {
|
||||
reflectTypeName = ""
|
||||
}
|
||||
@ -73,10 +79,10 @@ func doExport(value interface{}, indent string, buffer *bytes.Buffer, option doE
|
||||
case reflect.Slice, reflect.Array:
|
||||
if _, ok := value.([]byte); ok {
|
||||
if option.WithoutType {
|
||||
buffer.WriteString(fmt.Sprintf("\"%v\"\n", value))
|
||||
buffer.WriteString(fmt.Sprintf(`"%s"`, value))
|
||||
} else {
|
||||
buffer.WriteString(fmt.Sprintf(
|
||||
"%s(%d) \"%v\"\n",
|
||||
`%s(%d) "%s"`,
|
||||
reflectTypeName,
|
||||
len(reflectValue.String()),
|
||||
value,
|
||||
|
||||
@ -73,7 +73,7 @@ func Test_Dump(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DumpBrief(t *testing.T) {
|
||||
func TestDumpWithType(t *testing.T) {
|
||||
type CommonReq struct {
|
||||
AppId int64 `json:"appId" v:"required" in:"path" des:"应用Id" sum:"应用Id Summary"`
|
||||
ResourceId string `json:"resourceId" in:"query" des:"资源Id" sum:"资源Id Summary"`
|
||||
@ -127,6 +127,7 @@ func Test_DumpBrief(t *testing.T) {
|
||||
100: 100,
|
||||
})
|
||||
gutil.DumpWithType(req)
|
||||
gutil.DumpWithType([][]byte{[]byte("hello")})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ func (v *Validator) doCheckStruct(ctx context.Context, object interface{}) Error
|
||||
if _, ok := field.TagLookup(noValidationTagName); ok {
|
||||
continue
|
||||
}
|
||||
if err := v.doCheckStruct(ctx, field.Value); err != nil {
|
||||
if err = v.doCheckStruct(ctx, field.Value); err != nil {
|
||||
// It merges the errors into single error map.
|
||||
for k, m := range err.(*validationError).errors {
|
||||
errorMaps[k] = m
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user