new operator 'groupby'

This commit is contained in:
2026-05-02 14:46:28 +02:00
parent d5ced343c4
commit 3b2ef7927b
12 changed files with 271 additions and 58 deletions
+21 -4
View File
@@ -143,13 +143,12 @@ func (dict *DictType) HasKey(target any) (ok bool) {
return
}
func (dict *DictType) SetItem(key any, value any) (err error) {
func (dict *DictType) SetItem(key any, value any) {
(*dict)[key] = value
return
}
func (dict *DictType) GetItem(key any) (value any, err error) {
value = (*dict)[key]
func (dict *DictType) GetItem(key any) (value any, exists bool) {
value, exists = (*dict)[key]
return
}
@@ -169,6 +168,24 @@ func (dict *DictType) Merge(second *DictType) {
}
}
func (dict *DictType) Equals(dict2 DictType) (answer bool) {
if dict2 != nil && len(*dict) == len(dict2) {
answer = true
for key, value1 := range *dict {
if value2, exists := dict2.GetItem(key); exists {
if !Equal(value1, value2) {
answer = false
break
}
} else {
answer = false
break
}
}
}
return
}
////////////////
type DictFormat interface {
+14 -11
View File
@@ -220,11 +220,12 @@ func anyToFract(v any) (f *FractionType, err error) {
if f, ok = v.(*FractionType); !ok {
if n, ok := v.(int64); ok {
f = intToFraction(n)
} else if dec, ok := v.(float64); ok {
f, err = Float64ToFraction(dec)
} else {
err = ErrExpectedGot("fract", TypeFraction, v)
}
}
if f == nil {
err = ErrExpectedGot("fract", TypeFraction, v)
}
return
}
@@ -273,14 +274,16 @@ func CmpAnyFract(af1, af2 any) (result int, err error) {
// =0 if af1 == af2
// >0 if af1 > af2
func cmpFract(f1, f2 *FractionType) (result int) {
f2.num = -f2.num
f := SumFract(f1, f2)
if f.num < 0 {
result = -1
} else if f.num > 0 {
result = 1
} else {
result = 0
if f1 != nil && f2 != nil {
f2.num = -f2.num
f := SumFract(f1, f2)
if f.num < 0 {
result = -1
} else if f.num > 0 {
result = 1
} else {
result = 0
}
}
return
}
+22 -19
View File
@@ -50,13 +50,13 @@ func ListFromStrings(stringList []string) (list *ListType) {
return
}
func (ls *ListType) ToString(opt FmtOpt) (s string) {
func (dict *ListType) ToString(opt FmtOpt) (s string) {
indent := GetFormatIndent(opt)
flags := GetFormatFlags(opt)
var sb strings.Builder
sb.WriteByte('[')
if len(*ls) > 0 {
if len(*dict) > 0 {
innerOpt := MakeFormatOptions(flags, indent+1)
nest := strings.Repeat(" ", indent+1)
@@ -64,7 +64,7 @@ func (ls *ListType) ToString(opt FmtOpt) (s string) {
sb.WriteByte('\n')
sb.WriteString(nest)
}
for i, item := range []any(*ls) {
for i, item := range []any(*dict) {
if i > 0 {
if flags&MultiLine != 0 {
sb.WriteString(",\n")
@@ -96,19 +96,19 @@ func (ls *ListType) ToString(opt FmtOpt) (s string) {
return
}
func (ls *ListType) String() string {
return ls.ToString(0)
func (dict *ListType) String() string {
return dict.ToString(0)
}
func (ls *ListType) TypeName() string {
func (dict *ListType) TypeName() string {
return "list"
}
func (ls *ListType) Contains(t *ListType) (answer bool) {
if len(*ls) >= len(*t) {
func (dict *ListType) Contains(t *ListType) (answer bool) {
if len(*dict) >= len(*t) {
answer = true
for _, item := range *t {
if answer = ls.IndexDeepSameCmp(item) >= 0; !answer {
if answer = dict.IndexDeepSameCmp(item) >= 0; !answer {
break
}
}
@@ -120,8 +120,11 @@ func (ls1 *ListType) Equals(ls2 ListType) (answer bool) {
if ls2 != nil && len(*ls1) == len(ls2) {
answer = true
for index, i1 := range *ls1 {
// if i1 != (ls2)[index] {
if !reflect.DeepEqual(i1, ls2[index]) {
// if !reflect.DeepEqual(i1, ls2[index]) {
// answer = false
// break
// }
if !Equal(i1, ls2[index]) {
answer = false
break
}
@@ -130,11 +133,11 @@ func (ls1 *ListType) Equals(ls2 ListType) (answer bool) {
return
}
func (list *ListType) IndexDeepSameCmp(target any) (index int) {
func (dict *ListType) IndexDeepSameCmp(target any) (index int) {
var eq bool
var err error
index = -1
for i, item := range *list {
for i, item := range *dict {
if eq, err = deepSame(item, target, SameContent); err != nil {
break
} else if eq {
@@ -185,15 +188,15 @@ func deepSame(a, b any, deepCmp DeepFuncTemplate) (eq bool, err error) {
return
}
func (list *ListType) SetItem(index int64, value any) (err error) {
if index >= 0 && index < int64(len(*list)) {
(*list)[index] = value
func (dict *ListType) SetItem(index int64, value any) (err error) {
if index >= 0 && index < int64(len(*dict)) {
(*dict)[index] = value
} else {
err = fmt.Errorf("index %d out of bounds (0, %d)", index, len(*list)-1)
err = fmt.Errorf("index %d out of bounds (0, %d)", index, len(*dict)-1)
}
return
}
func (list *ListType) AppendItem(value any) {
*list = append(*list, value)
func (dict *ListType) AppendItem(value any) {
*dict = append(*dict, value)
}