github.com/mymmsc/gox@v1.3.33/util/lambda/array.go (about) 1 package lambda 2 3 import ( 4 "errors" 5 "fmt" 6 "reflect" 7 "strings" 8 ) 9 10 // make Array from source(TIn[] type) 11 // source support array or slice type 12 func LambdaArray(source interface{}) Array { 13 t := reflect.TypeOf(source) 14 arr := _array{source, t, t.Elem(), reflect.ValueOf(source)} 15 if !arr.IsSlice() { 16 err := fmt.Errorf("source type is %s, not array ", arr.arrayType.Kind()) 17 panic(err) 18 } 19 return &arr 20 } 21 22 type Array interface { 23 24 // return true when obj is slice 25 IsSlice() bool 26 27 // array join into string 28 // eg 29 // JoinOptions.express func(u user) string {return u.name } 30 // JoinOptions.Symbol default `,` 31 Join(options JoinOptions) string 32 33 // array filter 34 // eg: arr.Filter(func(ele int) bool{ return ele>10}) 35 Filter(express interface{}) Array 36 37 // sort by quick 38 // eg 39 Sort(express interface{}) Array 40 41 // sort by quick multithreading 42 SortMT(express interface{}) Array 43 44 // map to new array 45 // express func(el T) T{ return T } 46 Map(express interface{}) Array 47 48 // append element 49 Append(elements ...interface{}) Array 50 51 // maximum of array 52 // express eg: express func(ele TIn) TOut{ return TOut },TOut must be number Type or Compare 53 Max(express interface{}) interface{} 54 55 // minimum of array 56 // express eg: express func(ele TIn) TOut{ return TOut },TOut must be number Type or Compare 57 Min(express interface{}) interface{} 58 59 // Determines whether the Array contains any elements 60 Any(express interface{}) bool 61 62 // Determines whether the condition is satisfied for all elements in the Array 63 All(express interface{}) bool 64 65 // Returns a number indicating how many elements in the specified Array satisfy the condition 66 Count(express interface{}) int 67 68 // Returns the first element of an Array that satisfies the condition 69 First(express interface{}) (interface{}, error) 70 71 // Returns the last element of an Array that satisfies the condition 72 Last(express interface{}) (interface{}, error) 73 74 // Returns the zero based index of the first occurrence in an Array 75 Index(i int) (interface{}, error) 76 77 // skip and Returns the elements 78 Take(skip, count int) Array 79 80 // sum of the values returned by the expression 81 Sum(express interface{}) interface{} 82 83 // average of the values returned by the expression 84 Average(express interface{}) float64 85 86 // Determines whether the array contains the specified element 87 // number type use default comparator 88 // other type can implements Compare 89 Contains(express interface{}) bool 90 91 // array or slice pointer 92 // Array.Pointer().([]T or [n]T) 93 Pointer() interface{} 94 } 95 96 func innerLambdaArray(value reflect.Value) Array { 97 t := value.Type() 98 arr := _array{value, t, t.Elem(), value} 99 return &arr 100 } 101 102 type _array struct { 103 104 // source array 105 source interface{} 106 // array type 107 arrayType reflect.Type 108 // element type 109 elementType reflect.Type 110 // value type 111 value reflect.Value 112 } 113 114 func (p *_array) Contains(express interface{}) bool { 115 sz := p.Len() 116 if express == nil { 117 panic("express is null") 118 } 119 if t := reflect.TypeOf(express); t.Kind() == reflect.Func { 120 expType := reflect.TypeOf(express) 121 checkExpress(expType, []reflect.Type{p.elementType}, []reflect.Type{reflect.TypeOf(true)}) 122 fn := reflect.ValueOf(express) 123 for i := 0; i < sz; i++ { 124 ret := fn.Call([]reflect.Value{p.value.Index(i)}) 125 if ret[0].Interface().(bool) { 126 return true 127 } 128 } 129 } else if tor, err := BasicComparator(express); err == nil { 130 for i := 0; i < sz; i++ { 131 if tor.CompareTo(p.value.Index(i).Interface()) == 0 { 132 return true 133 } 134 } 135 } else if eq, ok := express.(Equal); ok { 136 for i := 0; i < sz; i++ { 137 if eq.Equals(p.value.Index(i).Interface()) { 138 return true 139 } 140 } 141 } else { 142 panic("unknown type " + t.String()) 143 } 144 return false 145 } 146 147 func (p *_array) Average(express interface{}) float64 { 148 length := p.Len() 149 if length == 0 { 150 return float64(0) 151 } 152 sum := p.Sum(express) 153 154 switch sum.(type) { 155 case int: 156 return float64(sum.(int)) / float64(length) 157 case uint8: 158 return float64(sum.(uint8)) / float64(length) 159 case uint16: 160 return float64(sum.(uint16)) / float64(length) 161 case uint32: 162 return float64(sum.(uint32)) / float64(length) 163 case uint64: 164 return float64(sum.(uint64)) / float64(length) 165 case int8: 166 return float64(sum.(int8)) / float64(length) 167 case int16: 168 return float64(sum.(int16)) / float64(length) 169 case int32: 170 return float64(sum.(int32)) / float64(length) 171 case int64: 172 return float64(sum.(int64)) / float64(length) 173 case float32: 174 return float64(sum.(float32)) / float64(length) 175 case float64: 176 return sum.(float64) / float64(length) 177 default: 178 panic("unknown type " + reflect.TypeOf(sum).String()) 179 } 180 } 181 182 func (p *_array) Append(elements ...interface{}) Array { 183 ret := LambdaArray(elements).Map(func(ele interface{}) reflect.Value { 184 if t := reflect.TypeOf(ele); t.Kind() != p.elementType.Kind() { 185 panic(fmt.Sprintf("element type[%s] is not %s.", t.String(), p.elementType.String())) 186 } 187 return reflect.ValueOf(ele) 188 }).Pointer().([]reflect.Value) 189 p.value = reflect.Append(p.value, ret...) 190 return p 191 } 192 193 func (p *_array) Any(express interface{}) bool { 194 if express == nil { 195 return p.Len() > 0 196 } 197 checkExpress( 198 reflect.TypeOf(express), 199 []reflect.Type{p.elementType}, 200 []reflect.Type{reflect.TypeOf(true)}) 201 202 length := p.Len() 203 fn := reflect.ValueOf(express) 204 for i := 0; i < length; i++ { 205 if fn.Call([]reflect.Value{p.value.Index(i)})[0].Interface().(bool) { 206 return true 207 } 208 } 209 return false 210 } 211 212 func (p *_array) All(express interface{}) bool { 213 if express == nil { 214 return p.Len() > 0 215 } 216 checkExpress( 217 reflect.TypeOf(express), 218 []reflect.Type{p.elementType}, 219 []reflect.Type{reflect.TypeOf(true)}) 220 length := p.Len() 221 fn := reflect.ValueOf(express) 222 for i := 0; i < length; i++ { 223 if !fn.Call([]reflect.Value{p.value.Index(i)})[0].Interface().(bool) { 224 return false 225 } 226 } 227 if p.Len() > 0 { 228 return true 229 } else { 230 return false 231 } 232 } 233 234 func (p *_array) Count(express interface{}) int { 235 if express == nil { 236 return p.Len() 237 } 238 checkExpress( 239 reflect.TypeOf(express), 240 []reflect.Type{p.elementType}, 241 []reflect.Type{reflect.TypeOf(true)}) 242 fn := reflect.ValueOf(express) 243 count := 0 244 p.EachV(func(v reflect.Value, _ int) { 245 if fn.Call([]reflect.Value{v})[0].Interface().(bool) { 246 count++ 247 } 248 }) 249 return count 250 } 251 252 func (p *_array) Find(express interface{}, start, step int) (interface{}, error) { 253 length := p.Len() 254 if length == 0 { 255 return nil, errors.New("empty array") 256 } 257 258 if express == nil { 259 return p.value.Index(0).Interface(), nil 260 } 261 checkExpress( 262 reflect.TypeOf(express), 263 []reflect.Type{p.elementType}, 264 []reflect.Type{reflect.TypeOf(true)}) 265 fn := reflect.ValueOf(express) 266 for i := start; i < length && i >= 0; i += step { 267 if ele := p.value.Index(i); fn.Call([]reflect.Value{ele})[0].Interface().(bool) { 268 return ele.Interface(), nil 269 } 270 } 271 return nil, errors.New("not found") 272 } 273 274 func (p *_array) First(express interface{}) (interface{}, error) { 275 return p.Find(express, 0, 1) 276 } 277 278 func (p *_array) Last(express interface{}) (interface{}, error) { 279 return p.Find(express, p.Len()-1, -1) 280 } 281 282 func (p *_array) Index(i int) (interface{}, error) { 283 if i < p.Len() { 284 return p.value.Index(i), nil 285 } 286 return nil, errors.New(fmt.Sprintf("%d out of range", i)) 287 } 288 289 func (p *_array) Take(skip, count int) Array { 290 length := p.value.Len() 291 292 ret := reflect.MakeSlice(p.arrayType, 0, 0) 293 for i := skip; i < length; i++ { 294 if count > 0 { 295 ret = reflect.Append(ret, p.value.Index(i)) 296 count-- 297 } 298 if count == 0 { 299 break 300 } 301 } 302 return innerLambdaArray(ret) 303 } 304 305 func (p *_array) Sum(express interface{}) interface{} { 306 307 var add Add 308 if express == nil { 309 add = Adder(p.elementType) 310 } else { 311 checkExpress( 312 reflect.TypeOf(express), 313 []reflect.Type{p.elementType}, 314 nil) 315 add = Adder(reflect.TypeOf(express).Out(0)) 316 } 317 318 length := p.Len() 319 if length == 0 { 320 return add.Value() 321 } 322 323 fn := reflect.ValueOf(express) 324 325 fv := func(i int) reflect.Value { 326 v := p.value.Index(i) 327 if express == nil { 328 return v 329 } 330 return fn.Call([]reflect.Value{v})[0] 331 } 332 333 for i := 0; i < length; i++ { 334 add.Add(fv(i)) 335 } 336 return add.Value() 337 } 338 339 func (p *_array) Pointer() interface{} { 340 return p.value.Interface() 341 } 342 343 func (p *_array) IsSlice() bool { 344 return p.arrayType.Kind() == reflect.Slice || p.arrayType.Kind() == reflect.Array 345 } 346 347 func (p *_array) Len() int { 348 return p.value.Len() 349 } 350 351 // check the function express 352 // exp the express function type 353 // in express function parameter types 354 // out express function return types 355 func checkExpress(exp reflect.Type, in []reflect.Type, out []reflect.Type) { 356 if exp.Kind() != reflect.Func { 357 panic("express is not a func express") 358 } 359 // check in 360 numIn := exp.NumIn() 361 lenIn := len(in) 362 if numIn != lenIn { 363 panic(fmt.Errorf("lambda express parameter count must be %d", lenIn)) 364 } 365 for i := 0; i < lenIn; i++ { 366 if in[i].Kind() != exp.In(i).Kind() { 367 panic(fmt.Errorf("lambda express the %d'th parameter Type must be %s,not %s,func=%s", 368 i, exp.In(i).String(), in[i].String(), exp.String())) 369 } 370 } 371 if out == nil { 372 return 373 } 374 // check output 375 numOut := exp.NumOut() 376 lenOut := len(out) 377 if numOut != lenOut { 378 panic(fmt.Errorf("lambda express return Types count must be %d", lenOut)) 379 } 380 for i := 0; i < lenOut; i++ { 381 if out[i].Kind() != exp.Out(i).Kind() { 382 panic(fmt.Errorf("lambda express the %d'th return Type must be %s", i, exp.Out(i).String())) 383 } 384 } 385 } 386 387 // check the function express 388 func checkExpressRARTO(express interface{}, in []reflect.Type) reflect.Type { 389 t := reflect.TypeOf(express) 390 if t.NumOut() == 0 { 391 panic("lambda express must has only one return-value.") 392 } 393 ot := t.Out(0) 394 checkExpress(t, in, []reflect.Type{ot}) 395 return ot 396 } 397 398 func (p *_array) Map(express interface{}) Array { 399 in := []reflect.Type{p.elementType} 400 ot := checkExpressRARTO(express, in) 401 402 var result reflect.Value 403 length := p.Len() 404 // slice or array 405 isSlice := p.arrayType.Kind() == reflect.Slice 406 var element reflect.Value 407 if isSlice { 408 result = reflect.MakeSlice(reflect.SliceOf(ot), p.Len(), p.Len()) 409 element = result 410 } else { 411 result = reflect.New(reflect.ArrayOf(length, ot)) 412 element = result.Elem() 413 } 414 415 funcValue := reflect.ValueOf(express) 416 params := []reflect.Value{reflect.ValueOf(0)} 417 for i := 0; i < length; i++ { 418 params[0] = p.value.Index(i) 419 trans := funcValue.Call(params) 420 v := element.Index(i) 421 v.Set(trans[0]) 422 } 423 424 return innerLambdaArray(result) 425 } 426 427 type JoinOptions struct { 428 Symbol string 429 express interface{} 430 } 431 432 func (p *_array) Join(option JoinOptions) string { 433 if option.express != nil { 434 return p.Map(option.express).Join(JoinOptions{Symbol: option.Symbol}) 435 } 436 if p.elementType.Kind() != reflect.String { 437 panic("the array is not string array") 438 } 439 if option.Symbol == "" { 440 option.Symbol = "," 441 } 442 length := p.Len() 443 var build strings.Builder 444 for i := 0; i < length; i++ { 445 s := p.value.Index(i).Interface().(string) 446 build.WriteString(s) 447 if i < length-1 { 448 build.WriteString(option.Symbol) 449 } 450 } 451 return build.String() 452 } 453 454 func (p *_array) Filter(express interface{}) Array { 455 in := []reflect.Type{p.elementType} 456 ft := reflect.TypeOf(express) 457 ot := reflect.TypeOf(true) 458 checkExpress(ft, in, []reflect.Type{ot}) 459 460 ret := reflect.MakeSlice(reflect.SliceOf(p.elementType), 0, 0) 461 funcValue := reflect.ValueOf(express) 462 params := []reflect.Value{reflect.ValueOf(0)} 463 length := p.Len() 464 for i := 0; i < length; i++ { 465 params[0] = p.value.Index(i) 466 trans := funcValue.Call(params) 467 if trans[0].Interface().(bool) { 468 ret = reflect.Append(ret, params[0]) 469 } 470 } 471 return innerLambdaArray(ret) 472 } 473 474 func (p *_array) SortByBubble(express interface{}) Array { 475 in := []reflect.Type{p.elementType, p.elementType} 476 ft := reflect.TypeOf(express) 477 ot := reflect.TypeOf(true) 478 checkExpress(ft, in, []reflect.Type{ot}) 479 480 length := p.Len() 481 v := reflect.ValueOf(0) 482 funcValue := reflect.ValueOf(express) 483 params := []reflect.Value{v, v} 484 for i := 0; i < length-1; i++ { 485 for j := 0; j < length-i-1; j++ { 486 params[0] = p.value.Index(j) 487 params[1] = p.value.Index(j + 1) 488 trans := funcValue.Call(params) 489 if !trans[0].Interface().(bool) { 490 temp := params[0].Interface() 491 p.value.Index(j).Set(params[1]) 492 p.value.Index(j + 1).Set(reflect.ValueOf(temp)) 493 } 494 } 495 } 496 497 return p 498 } 499 500 func (p *_array) CopyValue() reflect.Value { 501 var arr reflect.Value 502 if p.IsSlice() { 503 arr = reflect.MakeSlice(reflect.SliceOf(p.elementType), p.Len(), p.Len()) 504 } else { 505 arr = reflect.New(reflect.ArrayOf(p.Len(), p.elementType)) 506 } 507 reflect.Copy(arr, p.value) 508 return arr 509 } 510 511 func (p *_array) Sort(express interface{}) Array { 512 in := []reflect.Type{p.elementType, p.elementType} 513 ft := reflect.TypeOf(express) 514 ot := reflect.TypeOf(true) 515 checkExpress(ft, in, []reflect.Type{ot}) 516 517 length := p.Len() 518 v := reflect.ValueOf(0) 519 funcValue := reflect.ValueOf(express) 520 params := []reflect.Value{v, v} 521 522 p.value = p.CopyValue() 523 524 compare := func(a reflect.Value, b int) bool { 525 params[0], params[1] = a, p.value.Index(b) 526 return funcValue.Call(params)[0].Interface().(bool) 527 } 528 529 var inner func(int, int) 530 // quick sort 531 inner = func(l, r int) { 532 if l < r { 533 i, j, x := l, r, p.value.Index(l) 534 x = reflect.ValueOf(x.Interface()) 535 for i < j { 536 for i < j && compare(x, j) { 537 j-- 538 } 539 if i < j { 540 p.value.Index(i).Set(p.value.Index(j)) 541 i++ 542 } 543 for i < j && !compare(x, i) { 544 i++ 545 } 546 if i < j { 547 p.value.Index(j).Set(p.value.Index(i)) 548 j-- 549 } 550 } 551 p.value.Index(i).Set(x) 552 inner(l, i-1) 553 inner(i+1, r) 554 } 555 } 556 inner(0, length-1) 557 return p 558 } 559 560 func (p *_array) SortMT(express interface{}) Array { 561 in := []reflect.Type{p.elementType, p.elementType} 562 ft := reflect.TypeOf(express) 563 ot := reflect.TypeOf(true) 564 checkExpress(ft, in, []reflect.Type{ot}) 565 566 funcValue := reflect.ValueOf(express) 567 568 compare := func(a, b reflect.Value) bool { 569 return funcValue.Call([]reflect.Value{a, b})[0].Interface().(bool) 570 } 571 var quick func(arr reflect.Value, ch chan reflect.Value) 572 quick = func(arr reflect.Value, ch chan reflect.Value) { 573 if arr.Len() == 1 { 574 ch <- arr.Index(0) 575 close(ch) 576 return 577 } 578 if arr.Len() == 0 { 579 close(ch) 580 return 581 } 582 583 left := reflect.MakeSlice(reflect.SliceOf(p.elementType), 0, 0) 584 right := reflect.MakeSlice(reflect.SliceOf(p.elementType), 0, 0) 585 length := arr.Len() 586 x := arr.Index(0) 587 for i := 1; i < length; i++ { 588 curr := arr.Index(i) 589 if compare(x, curr) { 590 left = reflect.Append(left, curr) 591 } else { 592 right = reflect.Append(right, curr) 593 } 594 } 595 lch := make(chan reflect.Value, left.Len()) 596 rch := make(chan reflect.Value, right.Len()) 597 go quick(left, lch) 598 go quick(right, rch) 599 for v := range lch { 600 ch <- v 601 } 602 ch <- x 603 for v := range rch { 604 ch <- v 605 } 606 close(ch) 607 } 608 ch := make(chan reflect.Value) 609 go quick(p.value, ch) 610 values := reflect.MakeSlice(reflect.SliceOf(p.elementType), 0, 0) 611 for v := range ch { 612 values = reflect.Append(values, v) 613 } 614 return innerLambdaArray(values) 615 } 616 617 func (p *_array) maxOrMin(express interface{}, isMax bool) interface{} { 618 if express != nil { 619 in := []reflect.Type{p.elementType} 620 ft := reflect.TypeOf(express) 621 ot := reflect.TypeOf(0) 622 checkExpress(ft, in, []reflect.Type{ot}) 623 } 624 var m reflect.Value 625 var mc interface{} 626 627 funcValue := reflect.ValueOf(express) 628 f := func(value reflect.Value) interface{} { 629 if express == nil { 630 return value.Interface() 631 } 632 return funcValue.Call([]reflect.Value{value})[0].Interface() 633 } 634 635 p.EachV(func(v reflect.Value, index int) { 636 vc := f(v) 637 if index == 0 { 638 m = v 639 mc = vc 640 } else { 641 tor, err := BasicComparator(vc) 642 if err != nil { 643 panic(err) 644 } 645 if isMax { 646 if tor.CompareTo(mc) > 0 { 647 m = v 648 mc = vc 649 } 650 } else { 651 if tor.CompareTo(mc) < 0 { 652 m = v 653 mc = vc 654 } 655 } 656 } 657 }) 658 return m.Interface() 659 } 660 661 func (p *_array) Max(express interface{}) interface{} { 662 return p.maxOrMin(express, true) 663 } 664 665 func (p *_array) Min(express interface{}) interface{} { 666 return p.maxOrMin(express, false) 667 } 668 669 func (p *_array) EachV(fn func(v reflect.Value, i int)) { 670 if fn == nil { 671 return 672 } 673 length := p.Len() 674 675 for i := 0; i < length; i++ { 676 fn(p.value.Index(i), i) 677 } 678 }