1
0
mirror of https://github.com/gogf/gf.git synced 2025-04-05 11:18:50 +08:00

change params order of Insert* functions for glist; improve gstr.IsNumber

This commit is contained in:
John 2019-10-01 16:35:44 +08:00
parent 6384e75ed9
commit e764b2393d
8 changed files with 140 additions and 14 deletions

View File

@ -0,0 +1,22 @@
package main
import (
"fmt"
"github.com/gogf/gf/container/glist"
)
func main() {
l := glist.New()
// Push
l.PushBack(1)
l.PushBack(2)
e0 := l.PushFront(0)
// Insert
l.InsertBefore(e0, -1)
l.InsertAfter(e0, "a")
fmt.Println(l)
// Pop
fmt.Println(l.PopFront())
fmt.Println(l.PopBack())
fmt.Println(l)
}

View File

@ -0,0 +1,23 @@
package main
import (
"encoding/json"
"fmt"
"github.com/gogf/gf/container/glist"
"github.com/gogf/gf/frame/g"
)
func main() {
type Student struct {
Id int
Name string
Scores *glist.List
}
s := Student{
Id: 1,
Name: "john",
Scores: glist.NewFrom(g.Slice{100, 99, 98}),
}
b, _ := json.Marshal(s)
fmt.Println(string(b))
}

View File

@ -0,0 +1,19 @@
package main
import (
"encoding/json"
"fmt"
"github.com/gogf/gf/container/glist"
)
func main() {
b := []byte(`{"Id":1,"Name":"john","Scores":[100,99,98]}`)
type Student struct {
Id int
Name string
Scores *glist.List
}
s := Student{}
json.Unmarshal(b, &s)
fmt.Println(s)
}

View File

@ -9,8 +9,11 @@
package glist
import (
"bytes"
"container/list"
"encoding/json"
"github.com/gogf/gf/text/gstr"
"github.com/gogf/gf/util/gconv"
"github.com/gogf/gf/internal/rwmutex"
)
@ -32,6 +35,20 @@ func New(safe ...bool) *List {
}
}
// NewFrom creates and returns a list from a copy of given slice <array>.
// The parameter <safe> used to specify whether using list in concurrent-safety,
// which is false in default.
func NewFrom(array []interface{}, safe ...bool) *List {
l := list.New()
for _, v := range array {
l.PushBack(v)
}
return &List{
mu: rwmutex.New(safe...),
list: l,
}
}
// PushFront inserts a new element <e> with value <v> at the front of list <l> and returns <e>.
func (l *List) PushFront(v interface{}) (e *Element) {
l.mu.Lock()
@ -275,7 +292,7 @@ func (l *List) PushFrontList(other *List) {
// InsertAfter inserts a new element <e> with value <v> immediately after <p> and returns <e>.
// If <p> is not an element of <l>, the list is not modified.
// The <p> must not be nil.
func (l *List) InsertAfter(v interface{}, p *Element) (e *Element) {
func (l *List) InsertAfter(p *Element, v interface{}) (e *Element) {
l.mu.Lock()
e = l.list.InsertAfter(v, p)
l.mu.Unlock()
@ -285,7 +302,7 @@ func (l *List) InsertAfter(v interface{}, p *Element) (e *Element) {
// InsertBefore inserts a new element <e> with value <v> immediately before <p> and returns <e>.
// If <p> is not an element of <l>, the list is not modified.
// The <p> must not be nil.
func (l *List) InsertBefore(v interface{}, p *Element) (e *Element) {
func (l *List) InsertBefore(p *Element, v interface{}) (e *Element) {
l.mu.Lock()
e = l.list.InsertBefore(v, p)
l.mu.Unlock()
@ -373,6 +390,34 @@ func (l *List) IteratorDesc(f func(e *Element) bool) {
l.mu.RUnlock()
}
// Join joins list elements with a string <glue>.
func (l *List) Join(glue string) string {
l.mu.RLock()
defer l.mu.RUnlock()
buffer := bytes.NewBuffer(nil)
length := l.list.Len()
if length > 0 {
s := ""
for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
s = gconv.String(e.Value)
if gstr.IsNumeric(s) {
buffer.WriteString(s)
} else {
buffer.WriteString(`"` + gstr.QuoteMeta(s, `"\`) + `"`)
}
if i != length-1 {
buffer.WriteString(glue)
}
}
}
return buffer.String()
}
// String returns current list as a string.
func (l *List) String() string {
return "[" + l.Join(",") + "]"
}
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
func (l *List) MarshalJSON() ([]byte, error) {
return json.Marshal(l.FrontAll())

View File

@ -9,7 +9,6 @@ package glist
import (
"container/list"
"encoding/json"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/util/gconv"
@ -121,23 +120,23 @@ func TestList(t *testing.T) {
l.MoveToBack(e3) // should be no-op
checkListPointers(t, l, []*Element{e1, e4, e3})
e2 = l.InsertBefore(2, e1) // insert before front
e2 = l.InsertBefore(e1, 2) // insert before front
checkListPointers(t, l, []*Element{e2, e1, e4, e3})
l.Remove(e2)
e2 = l.InsertBefore(2, e4) // insert before middle
e2 = l.InsertBefore(e4, 2) // insert before middle
checkListPointers(t, l, []*Element{e1, e2, e4, e3})
l.Remove(e2)
e2 = l.InsertBefore(2, e3) // insert before back
e2 = l.InsertBefore(e3, 2) // insert before back
checkListPointers(t, l, []*Element{e1, e4, e2, e3})
l.Remove(e2)
e2 = l.InsertAfter(2, e1) // insert after front
e2 = l.InsertAfter(e1, 2) // insert after front
checkListPointers(t, l, []*Element{e1, e2, e4, e3})
l.Remove(e2)
e2 = l.InsertAfter(2, e4) // insert after middle
e2 = l.InsertAfter(e4, 2) // insert after middle
checkListPointers(t, l, []*Element{e1, e4, e2, e3})
l.Remove(e2)
e2 = l.InsertAfter(2, e3) // insert after back
e2 = l.InsertAfter(e3, 2) // insert after back
checkListPointers(t, l, []*Element{e1, e4, e3, e2})
l.Remove(e2)
@ -265,7 +264,7 @@ func TestIssue4103(t *testing.T) {
t.Errorf("l2.Len() = %d, want 2", n)
}
l1.InsertBefore(8, e)
l1.InsertBefore(e, 8)
if n := l1.Len(); n != 3 {
t.Errorf("l1.Len() = %d, want 3", n)
}
@ -348,7 +347,7 @@ func TestInsertBeforeUnknownMark(t *testing.T) {
l.PushBack(1)
l.PushBack(2)
l.PushBack(3)
l.InsertBefore(1, new(Element))
l.InsertBefore(new(Element), 1)
checkList(t, l, []interface{}{1, 2, 3})
}
@ -358,7 +357,7 @@ func TestInsertAfterUnknownMark(t *testing.T) {
l.PushBack(1)
l.PushBack(2)
l.PushBack(3)
l.InsertAfter(1, new(Element))
l.InsertAfter(new(Element), 1)
checkList(t, l, []interface{}{1, 2, 3})
}
@ -585,6 +584,21 @@ func TestList_Iterator(t *testing.T) {
checkList(t, l, []interface{}{"e", "d", "c", "b", "a"})
}
func TestList_Join(t *testing.T) {
gtest.Case(t, func() {
l := NewFrom([]interface{}{1, 2, "a", `"b"`, `\c`})
gtest.Assert(l.Join(","), `1,2,"a","\"b\"","\\c"`)
gtest.Assert(l.Join("."), `1.2."a"."\"b\""."\\c"`)
})
}
func TestList_String(t *testing.T) {
gtest.Case(t, func() {
l := NewFrom([]interface{}{1, 2, "a", `"b"`, `\c`})
gtest.Assert(l.String(), `[1,2,"a","\"b\"","\\c"]`)
})
}
func TestList_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {

View File

@ -33,6 +33,9 @@ func IsNumeric(s string) bool {
return false
}
for i := 0; i < len(s); i++ {
if s[i] == '-' && i == 0 {
continue
}
if s[i] == '.' {
if i > 0 && i < len(s)-1 {
continue

View File

@ -143,7 +143,7 @@ func (s *Server) setHandler(pattern string, handler *handlerItem) {
item = e.Value.(*handlerItem)
// 判断优先级,决定当前注册项的插入顺序
if s.compareRouterPriority(handler, item) {
l.InsertBefore(handler, e)
l.InsertBefore(e, handler)
pushed = true
goto end
}

View File

@ -140,7 +140,7 @@ func (s *Server) searchHandlers(method, path, domain string) (parsedItems []*han
if lastMiddlewareElem == nil {
lastMiddlewareElem = parsedItemList.PushFront(parsedItem)
} else {
lastMiddlewareElem = parsedItemList.InsertAfter(parsedItem, lastMiddlewareElem)
lastMiddlewareElem = parsedItemList.InsertAfter(lastMiddlewareElem, parsedItem)
}
// 钩子函数存在性判断