Giter VIP home page Giter VIP logo

Comments (8)

wangbintao1992 avatar wangbintao1992 commented on June 20, 2024

pair.go

package util

import (
	"container/list"
	"encoding/json"
	"fmt"
	"github.com/ecodeclub/ekit/reflectx"
	"reflect"
)

// Pair
type Pair[F any, S any] struct {
	first     F
	second    S
	ignoreNil bool
}

type pairJson[F any, S any] struct {
	First  F `json:"first"`
	Second S `json:"second"`
}

func (p *Pair[F, S]) toJson() string {
	if byteJson, err := json.Marshal(&pairJson[F, S]{First: p.first, Second: p.second}); err == nil {
		return string(byteJson)
	}

	return ""
}
func ParsePair[F any, S any](pair *Pair[F, S], jsonStr string) error {
	p := &pairJson[F, S]{}
	err := json.Unmarshal([]byte(jsonStr), p)

	if err == nil {
		pair.SetFirst(p.First)
		pair.SetSecond(p.Second)

		return nil
	}

	return err
}

func (p *Pair[F, S]) ToList() *list.List {
	return p.toListCallBack(nil)
}

func (p *Pair[F, S]) ToArray() []any {
	return p.toArrayCallBack(nil)
}

func (p *Pair[F, S]) toArrayCallBack(cb func() any) []any {
	var array []interface{}
	array = append(array, p.first)
	array = append(array, p.second)

	if cb != nil {
		array = append(array, cb())
	}

	return array
}

func (p *Pair[F, S]) toListCallBack(cb func() any) *list.List {
	list := list.New()
	list.PushBack(p.first)
	list.PushBack(p.second)

	if cb != nil {

		list.PushBack(cb())
	}

	return list
}
func (p *Pair[F, S]) Copy(value *Pair[F, S]) *Pair[F, S] {
	if p.ignoreNil {
		if !reflectx.IsNilValue(reflect.ValueOf(value.first)) {
			p.first = value.first
		}

		if !reflectx.IsNilValue(reflect.ValueOf(value.second)) {
			p.second = value.second
		}
	} else {
		p.first = value.first
		p.second = value.second
	}

	return p
}

func NewPair[F any, S any](first F, second S) *Pair[F, S] {
	return &Pair[F, S]{first: first, second: second}
}

func NewPairIgnoreNil[F any, S any](first F, second S) *Pair[F, S] {
	return &Pair[F, S]{first: first, second: second, ignoreNil: true}
}

func (p *Pair[F, S]) ToString() string {
	return p.toStringCallBack(nil)
}

func (p *Pair[F, S]) toStringCallBack(cb func() string) string {
	if cb != nil {
		return "<" + fmt.Sprintf("%#v", p.first) + "," + fmt.Sprintf("%#v", p.second) + "," + cb() + ">"
	}

	return "<" + fmt.Sprintf("%#v", p.first) + "," + fmt.Sprintf("%#v", p.second) + ">"
}

func (p *Pair[F, S]) IgnoreNil() bool {
	return p.ignoreNil
}

func (p *Pair[F, S]) SetIgnoreNil(ignoreNil bool) {
	p.ignoreNil = ignoreNil
}

func (p *Pair[F, S]) First() F {
	return p.first
}

func (p *Pair[F, S]) SetFirst(first F) {
	p.first = first
}

func (p *Pair[F, S]) Second() S {
	return p.second
}

func (p *Pair[F, S]) SetSecond(second S) {
	p.second = second
}

// Triple
type Triple[F any, S any, T any] struct {
	*Pair[F, S]
	third T
}

type tripleJson[F any, S any, T any] struct {
	First  F `json:"first"`
	Second S `json:"second"`
	Third  T `json:"third"`
}

func (t *Triple[F, S, T]) Third() T {
	return t.third
}

func (t *Triple[F, S, T]) SetThird(third T) {
	t.third = third
}

func (t *Triple[F, S, T]) ToList() *list.List {
	return t.Pair.toListCallBack(func() any {
		return t.third
	})
}

func (t *Triple[F, S, T]) ToString() string {
	return t.Pair.toStringCallBack(func() string {
		return fmt.Sprintf("%#v", t.third)
	})
}

func (t *Triple[F, S, T]) ToArray() []any {
	return t.Pair.toArrayCallBack(func() any {
		return t.third
	})
}

func (t *Triple[F, S, T]) toJson() string {

	if byteJson, err := json.Marshal(&tripleJson[F, S, T]{First: t.first, Second: t.second, Third: t.third}); err == nil {
		return string(byteJson)
	}

	return ""
}

func ParseTriple[F any, S any, T any](triple *Triple[F, S, T], jsonStr string) error {
	t := &tripleJson[F, S, T]{}
	err := json.Unmarshal([]byte(jsonStr), t)

	if err == nil {
		triple.Pair = NewPair(t.First, t.Second)
		triple.SetThird(t.Third)

		return nil
	}

	return err
}

func (t *Triple[F, S, T]) Copy(value *Triple[F, S, T]) *Triple[F, S, T] {
	t.Pair.Copy(value.Pair)

	if t.ignoreNil {
		if !reflectx.IsNilValue(reflect.ValueOf(value.third)) {
			t.third = value.third
		}
	} else {
		t.third = value.third
	}

	return t
}

pair_test.go

package util

import (
	"fmt"
	"reflect"
	"testing"
	"time"
)

type Test struct {
	Name string
	Age  int
	Date time.Time
}

func TestTriple(t *testing.T) {
	triple := NewTriple("kobe", 2, time.Now())

	fmt.Println("first :", triple.First())
	fmt.Println("first type:", reflect.TypeOf(triple.First()))

	fmt.Println("second :", triple.Second())
	fmt.Println("second type:", reflect.TypeOf(triple.Second()))

	fmt.Println("third :", triple.Third())
	fmt.Println("third type:", reflect.TypeOf(triple.Third()))

	fmt.Println("toList:", triple.ToList())
	fmt.Println("toString:", triple.ToString())
	fmt.Println("json:", triple.toJson())

	m := make(map[int]string)
	m[1] = "new one"
	m[2] = "new two"

	fmt.Println("copy:", triple.Copy(NewTriple("james", 99, time.Now())).ToString())

	jsonStr := "{\"first\":\"jordan\",\"second\":5}"

	tripleJson := &Triple[string, int, time.Time]{}
	ParseTriple(tripleJson, jsonStr)
	fmt.Println("json first:", tripleJson.First())
	fmt.Println("json second:", tripleJson.Second())
	fmt.Println("json third:", tripleJson.Third())
}

func NewTriple[F any, S any, T any](first F, second S, third T) *Triple[F, S, T] {
	return &Triple[F, S, T]{Pair: NewPair(first, second), third: third}
}

func TestPair(t *testing.T) {
	m := make(map[string]int)
	m["A"] = 1
	m["B"] = 2
	pair2 := NewPair(m, 1)

	fmt.Println("first:", pair2.First())
	fmt.Println("first type:", reflect.TypeOf(pair2.First()))
	fmt.Println("second:", pair2.Second())
	fmt.Println("second type:", reflect.TypeOf(pair2.Second()))
	fmt.Println("tostring:", pair2.ToString())
	fmt.Println("toList:", pair2.ToList())
	fmt.Println("toArray:", pair2.ToArray())
	fmt.Println("copy:", pair2.Copy(NewPair(make(map[string]int), 2)))
	fmt.Println("json:", pair2.toJson())

	jsonStr := "{\"first\":{\"C\":3,\"D\":4},\"second\":9}"
	p := &Pair[map[string]int, int]{}
	ParsePair(p, jsonStr)

	fmt.Println("json first:", p.first)
	fmt.Println("json second:", p.second)
}

func TestPairIgnoreNil(t *testing.T) {
	newPair := NewPairIgnoreNil(&Test{Name: "tester", Age: 99, Date: time.Now()}, float64(99))

	copyValue := &Pair[*Test, float64]{first: nil, second: 88}

	fmt.Println("first:", newPair.First())
	fmt.Println("first:", newPair.first.Name, newPair.first.Age, newPair.first.Date.String())
	fmt.Println("first type:", reflect.TypeOf(newPair.First()))
	fmt.Println("second:", newPair.Second())
	fmt.Println("second type:", reflect.TypeOf(newPair.Second()))
	fmt.Println("toString:", newPair.ToString())
	fmt.Println("toList:", newPair.ToList())
	fmt.Println("toArray:", newPair.ToArray())
	fmt.Println("copy:", newPair.Copy(copyValue))

	fmt.Println("json:", newPair.toJson())
}
image image

from ekit.

longyue0521 avatar longyue0521 commented on June 20, 2024

@wangbintao1992

当前实现中toList/toArray的使用场景是什么? First,Second,Third本身不就表示了逻辑上的“list/array”有顺序的概念了吗?

  1. 参考 #164 中的讨论及本issue 自查一下你当前的实现
  2. 觉得没问题 参考 https://ekit.gocn.vip/contribution/ 提一个独立的PR, 我们在PR中进行针对性讨论

from ekit.

flycash avatar flycash commented on June 20, 2024

可以直接提合并请求,这样我们比较好 review 代码 😄

from ekit.

wangbintao1992 avatar wangbintao1992 commented on June 20, 2024

没勇气提pr啊....

from ekit.

KirinRyuuri avatar KirinRyuuri commented on June 20, 2024

没勇气提pr啊....

怕什么,大不了被拒 [滑稽]
而且你写的也不差,勇敢一点

from ekit.

flycash avatar flycash commented on June 20, 2024

还是直接发 PR,我们比较好管理

from ekit.

dxyinme avatar dxyinme commented on June 20, 2024

感觉对于Pair的函数定义来说,Copy应该还是用于复制自身,然后需要一个MergeFrom来更新会比较好

from ekit.

flycash avatar flycash commented on June 20, 2024

Pair 已经解决了,等后面有需要的时候,再来解决 tuple 的问题

from ekit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.