github.com/PandaGoAdmin/utils@v0.0.0-20211208134815-d5461603a00f/array.go (about) 1 package kgo 2 3 import ( 4 "bytes" 5 "fmt" 6 "math" 7 "math/rand" 8 "reflect" 9 "sort" 10 "strconv" 11 "strings" 12 "time" 13 ) 14 15 // ArrayKeys 返回数组(切片/字典/结构体)中所有的键名;如果是结构体,只返回公开的字段. 16 func (ka *LkkArray) ArrayKeys(arr interface{}) []interface{} { 17 val := reflect.ValueOf(arr) 18 typ := val.Kind() 19 if typ != reflect.Array && typ != reflect.Slice && typ != reflect.Struct && typ != reflect.Map { 20 panic("[ArrayKeys]`arr type must be array|slice|map|struct; but : " + typ.String()) 21 } 22 23 var res []interface{} 24 switch typ { 25 case reflect.Array, reflect.Slice: 26 for i := 0; i < val.Len(); i++ { 27 res = append(res, i) 28 } 29 case reflect.Map: 30 for _, k := range val.MapKeys() { 31 res = append(res, k) 32 } 33 case reflect.Struct: 34 var t = val.Type() 35 for i := 0; i < t.NumField(); i++ { 36 field := t.Field(i) 37 // 不能访问未导出的字段 38 if field.PkgPath != "" { 39 continue 40 } 41 res = append(res, field.Name) 42 } 43 } 44 45 return res 46 } 47 48 // ArrayValues 返回arr(数组/切片/字典/结构体)中所有的值;如果是结构体,只返回公开字段的值. 49 // filterZero 是否过滤零值元素(nil,false,0,"",[]),true时排除零值元素,false时保留零值元素. 50 func (ka *LkkArray) ArrayValues(arr interface{}, filterZero bool) []interface{} { 51 return arrayValues(arr, filterZero) 52 } 53 54 // ArrayChunk 将一个数组/切片分割成多个,size为每个子数组的长度. 55 func (ka *LkkArray) ArrayChunk(arr interface{}, size int) [][]interface{} { 56 if size < 1 { 57 panic("[ArrayChunk]`size cannot be less than 1") 58 } 59 60 val := reflect.ValueOf(arr) 61 switch val.Kind() { 62 case reflect.Array, reflect.Slice: 63 length := val.Len() 64 if length == 0 { 65 return nil 66 } 67 68 chunkNum := int(math.Ceil(float64(length) / float64(size))) 69 var res [][]interface{} 70 var item []interface{} 71 var start int 72 for i, end := 0, 0; chunkNum > 0; chunkNum-- { 73 end = (i + 1) * size 74 if end > length { 75 end = length 76 } 77 78 item = nil 79 start = i * size 80 for ; start < end; start++ { 81 item = append(item, val.Index(start).Interface()) 82 } 83 if item != nil { 84 res = append(res, item) 85 } 86 87 i++ 88 } 89 90 return res 91 default: 92 panic("[ArrayChunk]`arr type must be array|slice; but : " + val.Kind().String()) 93 } 94 } 95 96 // ArrayColumn 返回数组(切片/字典/结构体)中元素指定的一列. 97 // arr的元素必须是字典; 98 // columnKey为元素的字段名; 99 // 该方法效率较低. 100 func (ka *LkkArray) ArrayColumn(arr interface{}, columnKey string) []interface{} { 101 val := reflect.ValueOf(arr) 102 var res []interface{} 103 var err error 104 var item interface{} 105 switch val.Kind() { 106 case reflect.Array, reflect.Slice: 107 for i := 0; i < val.Len(); i++ { 108 item, err = GetFieldValue(val.Index(i).Interface(), columnKey) 109 if item != nil && err == nil { 110 res = append(res, item) 111 } 112 } 113 case reflect.Map: 114 for _, k := range val.MapKeys() { 115 item, err = GetFieldValue(val.MapIndex(k).Interface(), columnKey) 116 if item != nil && err == nil { 117 res = append(res, item) 118 } 119 } 120 case reflect.Struct: 121 for i := 0; i < val.NumField(); i++ { 122 item, err = GetFieldValue(reflect2Itf(val.Field(i)), columnKey) 123 if item != nil && err == nil { 124 res = append(res, item) 125 } 126 } 127 default: 128 panic("[ArrayColumn]`arr type must be array|slice|map|struct; but : " + val.Kind().String()) 129 } 130 131 return res 132 } 133 134 // SlicePush 将一个或多个元素压入切片的末尾(入栈),返回处理之后切片的元素个数. 135 func (ka *LkkArray) SlicePush(s *[]interface{}, elements ...interface{}) int { 136 *s = append(*s, elements...) 137 return len(*s) 138 } 139 140 // SlicePop 弹出切片最后一个元素(出栈),并返回该元素. 141 func (ka *LkkArray) SlicePop(s *[]interface{}) interface{} { 142 if len(*s) == 0 { 143 return nil 144 } 145 ep := len(*s) - 1 146 e := (*s)[ep] 147 *s = (*s)[:ep] 148 return e 149 } 150 151 // SliceUnshift 在切片开头插入一个或多个元素,返回处理之后切片的元素个数. 152 func (ka *LkkArray) SliceUnshift(s *[]interface{}, elements ...interface{}) int { 153 *s = append(elements, *s...) 154 return len(*s) 155 } 156 157 // SliceShift 将切片开头的元素移出,并返回该元素. 158 func (ka *LkkArray) SliceShift(s *[]interface{}) interface{} { 159 if len(*s) == 0 { 160 return nil 161 } 162 e := (*s)[0] 163 *s = (*s)[1:] 164 return e 165 } 166 167 // ArrayKeyExists 检查arr(数组/切片/字典/结构体)里是否有key指定的键名(索引/字段). 168 func (ka *LkkArray) ArrayKeyExists(key interface{}, arr interface{}) bool { 169 val := reflect.ValueOf(arr) 170 typ := val.Kind() 171 172 if typ != reflect.Array && typ != reflect.Slice && typ != reflect.Struct && typ != reflect.Map { 173 panic("[ArrayKeyExists]`arr type must be array|slice|map|struct; but : " + typ.String()) 174 } 175 176 if key == nil { 177 return false 178 } 179 180 switch typ { 181 case reflect.Array, reflect.Slice: 182 var keyInt int 183 var keyIsInt, ok bool 184 if keyInt, ok = key.(int); ok { 185 keyIsInt = true 186 } 187 188 length := val.Len() 189 if keyIsInt && length > 0 && keyInt >= 0 && keyInt < length { 190 return true 191 } 192 case reflect.Map: 193 for _, k := range val.MapKeys() { 194 if fmt.Sprintf("%s", key) == fmt.Sprintf("%s", k) || reflect.DeepEqual(key, k) { 195 return true 196 } 197 } 198 case reflect.Struct: 199 field := val.FieldByName(fmt.Sprintf("%s", key)) 200 if field.IsValid() { 201 return true 202 } 203 } 204 205 return false 206 } 207 208 // ArrayReverse 返回单元顺序相反的数组(仅限数组和切片). 209 func (ka *LkkArray) ArrayReverse(arr interface{}) []interface{} { 210 val := reflect.ValueOf(arr) 211 switch val.Kind() { 212 case reflect.Array, reflect.Slice: 213 length := val.Len() 214 res := make([]interface{}, length) 215 i, j := 0, length-1 216 for ; i < j; i, j = i+1, j-1 { 217 res[i], res[j] = val.Index(j).Interface(), val.Index(i).Interface() 218 } 219 if length > 0 && res[j] == nil { 220 res[j] = val.Index(j).Interface() 221 } 222 223 return res 224 default: 225 panic("[ArrayReverse]`arr type must be array|slice; but : " + val.Kind().String()) 226 } 227 } 228 229 // Implode 用delimiter将数组(数组/切片/字典/结构体)的值连接为一个字符串. 230 func (ka *LkkArray) Implode(delimiter string, arr interface{}) string { 231 val := reflect.ValueOf(arr) 232 var buf bytes.Buffer 233 var length, j int 234 switch val.Kind() { 235 case reflect.Array, reflect.Slice: 236 length = val.Len() 237 if length == 0 { 238 return "" 239 } 240 j = length 241 for i := 0; i < length; i++ { 242 buf.WriteString(toStr(val.Index(i).Interface())) 243 if j--; j > 0 { 244 buf.WriteString(delimiter) 245 } 246 } 247 case reflect.Map: 248 length = len(val.MapKeys()) 249 if length == 0 { 250 return "" 251 } 252 for _, k := range val.MapKeys() { 253 buf.WriteString(toStr(val.MapIndex(k).Interface())) 254 if length--; length > 0 { 255 buf.WriteString(delimiter) 256 } 257 } 258 case reflect.Struct: 259 length = val.NumField() 260 if length == 0 { 261 return "" 262 } 263 j = length 264 for i := 0; i < length; i++ { 265 j-- 266 if val.Field(i).CanInterface() { 267 buf.WriteString(toStr(val.Field(i).Interface())) 268 if j > 0 { 269 buf.WriteString(delimiter) 270 } 271 } 272 } 273 default: 274 panic("[Implode]`arr type must be array|slice|map|struct; but : " + val.Kind().String()) 275 } 276 277 return buf.String() 278 } 279 280 // JoinStrings 使用分隔符delimiter连接字符串切片strs.效率比Implode高. 281 func (ka *LkkArray) JoinStrings(delimiter string, strs []string) (res string) { 282 length := len(strs) 283 if length == 0 { 284 return 285 } 286 287 var sb strings.Builder 288 for _, str := range strs { 289 sb.WriteString(str) 290 if length--; length > 0 { 291 sb.WriteString(delimiter) 292 } 293 } 294 res = sb.String() 295 296 return 297 } 298 299 // JoinInts 使用分隔符delimiter连接整数切片. 300 func (ka *LkkArray) JoinInts(delimiter string, ints []int) (res string) { 301 length := len(ints) 302 if length == 0 { 303 return 304 } 305 306 var sb strings.Builder 307 for _, num := range ints { 308 sb.WriteString(strconv.Itoa(num)) 309 if length--; length > 0 { 310 sb.WriteString(delimiter) 311 } 312 } 313 res = sb.String() 314 315 return 316 } 317 318 // UniqueInts 移除整数切片中的重复值. 319 func (ka *LkkArray) UniqueInts(ints []int) (res []int) { 320 sort.Ints(ints) 321 var last int 322 for i, num := range ints { 323 if i == 0 || num != last { 324 res = append(res, num) 325 } 326 last = num 327 } 328 return 329 } 330 331 // Unique64Ints 移除64位整数切片中的重复值. 332 func (ka *LkkArray) Unique64Ints(ints []int64) (res []int64) { 333 seen := make(map[int64]bool) 334 for _, num := range ints { 335 if _, ok := seen[num]; !ok { 336 seen[num] = true 337 res = append(res, num) 338 } 339 } 340 return 341 } 342 343 // UniqueStrings 移除字符串切片中的重复值. 344 func (ka *LkkArray) UniqueStrings(strs []string) (res []string) { 345 sort.Strings(strs) 346 var last string 347 for _, str := range strs { 348 if str != last { 349 res = append(res, str) 350 } 351 last = str 352 } 353 354 return 355 } 356 357 // ArrayDiff 计算数组(数组/切片/字典)的交集,返回在 arr1 中但不在 arr2 里的元素,注意会同时返回键. 358 // compareType为两个数组的比较方式,枚举类型,有: 359 // COMPARE_ONLY_VALUE 根据元素值比较, 返回在 arr1 中但是不在arr2 里的值; 360 // COMPARE_ONLY_KEY 根据 arr1 中的键名和 arr2 进行比较,返回不同键名的项; 361 // COMPARE_BOTH_KEYVALUE 同时比较键和值. 362 func (ka *LkkArray) ArrayDiff(arr1, arr2 interface{}, compareType LkkArrCompareType) map[interface{}]interface{} { 363 valA := reflect.ValueOf(arr1) 364 valB := reflect.ValueOf(arr2) 365 typA := valA.Kind() 366 typB := valB.Kind() 367 368 if (typA != reflect.Array && typA != reflect.Slice && typA != reflect.Map) || (typB != reflect.Array && typB != reflect.Slice && typB != reflect.Map) { 369 panic("[ArrayDiff]`arr1,arr2 type must be array|slice|map; but : " + typA.String() + "/" + typB.String()) 370 } 371 372 lenA := valA.Len() 373 lenB := valB.Len() 374 if lenA == 0 { 375 return nil 376 } 377 378 resMap := make(map[interface{}]interface{}) 379 var iteA interface{} 380 var chkKey bool 381 var chkVal bool 382 var chkRes bool 383 384 if (typA == reflect.Array || typA == reflect.Slice) && (typB == reflect.Array || typB == reflect.Slice) { 385 //两者都是数组/切片 386 for i := 0; i < lenA; i++ { 387 iteA = valA.Index(i).Interface() 388 chkRes = true 389 390 if compareType == COMPARE_BOTH_KEYVALUE { 391 if i < lenB { 392 chkRes = !reflect.DeepEqual(iteA, valB.Index(i).Interface()) 393 } 394 } else if compareType == COMPARE_ONLY_KEY { 395 chkRes = lenB > 0 && i >= lenB 396 } else if compareType == COMPARE_ONLY_VALUE { 397 for j := 0; j < lenB; j++ { 398 chkRes = !reflect.DeepEqual(iteA, valB.Index(j).Interface()) 399 if !chkRes { 400 break 401 } 402 } 403 } 404 405 if chkRes { 406 resMap[i] = iteA 407 } 408 } 409 } else if (typA == reflect.Array || typA == reflect.Slice) && (typB == reflect.Map) { 410 //A是数组/切片,B是字典 411 for i := 0; i < lenA; i++ { 412 iteA = valA.Index(i).Interface() 413 chkRes = true 414 415 for _, k := range valB.MapKeys() { 416 chkKey = isInt(k.Interface()) && toInt(k.Interface()) == i 417 chkVal = reflect.DeepEqual(iteA, valB.MapIndex(k).Interface()) 418 419 if compareType == COMPARE_ONLY_KEY && chkKey { 420 chkRes = false 421 break 422 } else if compareType == COMPARE_ONLY_VALUE && chkVal { 423 chkRes = false 424 break 425 } else if compareType == COMPARE_BOTH_KEYVALUE && (chkKey && chkVal) { 426 chkRes = false 427 break 428 } 429 } 430 431 if chkRes { 432 resMap[i] = iteA 433 } 434 } 435 } else if (typA == reflect.Map) && (typB == reflect.Array || typB == reflect.Slice) { 436 //A是字典,B是数组/切片 437 var kv int 438 for _, k := range valA.MapKeys() { 439 iteA = valA.MapIndex(k).Interface() 440 chkRes = true 441 442 if isInt(k.Interface()) { 443 kv = toInt(k.Interface()) 444 } else { 445 kv = -1 446 } 447 448 if compareType == COMPARE_BOTH_KEYVALUE { 449 if kv >= 0 && kv < lenB { 450 chkRes = !reflect.DeepEqual(iteA, valB.Index(kv).Interface()) 451 } 452 } else if compareType == COMPARE_ONLY_KEY { 453 chkRes = (kv < 0 || kv >= lenB) 454 } else if compareType == COMPARE_ONLY_VALUE { 455 for i := 0; i < lenB; i++ { 456 chkRes = !reflect.DeepEqual(iteA, valB.Index(i).Interface()) 457 if !chkRes { 458 break 459 } 460 } 461 } 462 463 if chkRes { 464 resMap[k.Interface()] = iteA 465 } 466 } 467 } else if (typA == reflect.Map) && (typB == reflect.Map) { 468 //两者都是字典 469 var kv string 470 for _, k := range valA.MapKeys() { 471 iteA = valA.MapIndex(k).Interface() 472 chkRes = true 473 kv = toStr(k.Interface()) 474 475 for _, k2 := range valB.MapKeys() { 476 chkKey = kv == toStr(k2.Interface()) 477 chkVal = reflect.DeepEqual(iteA, valB.MapIndex(k2).Interface()) 478 479 if compareType == COMPARE_ONLY_KEY && chkKey { 480 chkRes = false 481 break 482 } else if compareType == COMPARE_ONLY_VALUE && chkVal { 483 chkRes = false 484 break 485 } else if compareType == COMPARE_BOTH_KEYVALUE && (chkKey || chkVal) { 486 chkRes = false 487 break 488 } 489 } 490 491 if chkRes { 492 resMap[k.Interface()] = iteA 493 } 494 } 495 } 496 497 return resMap 498 } 499 500 // ArrayIntersect 计算数组(数组/切片/字典)的交集,返回在 arr1 中且在 arr2 里的元素,注意会同时返回键. 501 // compareType为两个数组的比较方式,枚举类型,有: 502 // COMPARE_ONLY_VALUE 根据元素值比较, 返回在 arr1 中且在arr2 里的值; 503 // COMPARE_ONLY_KEY 根据 arr1 中的键名和 arr2 进行比较,返回相同键名的项; 504 // COMPARE_BOTH_KEYVALUE 同时比较键和值. 505 func (ka *LkkArray) ArrayIntersect(arr1, arr2 interface{}, compareType LkkArrCompareType) map[interface{}]interface{} { 506 valA := reflect.ValueOf(arr1) 507 valB := reflect.ValueOf(arr2) 508 typA := valA.Kind() 509 typB := valB.Kind() 510 511 if (typA != reflect.Array && typA != reflect.Slice && typA != reflect.Map) || (typB != reflect.Array && typB != reflect.Slice && typB != reflect.Map) { 512 panic("[ArrayIntersect]`arr1,arr2 type must be array|slice|map; but : " + typA.String() + "/" + typB.String()) 513 } 514 515 lenA := valA.Len() 516 lenB := valB.Len() 517 if lenA == 0 || lenB == 0 { 518 return nil 519 } 520 521 resMap := make(map[interface{}]interface{}) 522 var iteA interface{} 523 var chkKey bool 524 var chkVal bool 525 var chkRes bool 526 527 if (typA == reflect.Array || typA == reflect.Slice) && (typB == reflect.Array || typB == reflect.Slice) { 528 //两者都是数组/切片 529 for i := 0; i < lenA; i++ { 530 iteA = valA.Index(i).Interface() 531 chkRes = false 532 533 if compareType == COMPARE_BOTH_KEYVALUE { 534 if i < lenB { 535 chkRes = reflect.DeepEqual(iteA, valB.Index(i).Interface()) 536 } 537 } else if compareType == COMPARE_ONLY_KEY { 538 chkRes = i < lenB 539 } else if compareType == COMPARE_ONLY_VALUE { 540 for j := 0; j < lenB; j++ { 541 chkRes = reflect.DeepEqual(iteA, valB.Index(j).Interface()) 542 if chkRes { 543 break 544 } 545 } 546 } 547 548 if chkRes { 549 resMap[i] = iteA 550 } 551 } 552 } else if (typA == reflect.Array || typA == reflect.Slice) && (typB == reflect.Map) { 553 //A是数组/切片,B是字典 554 for i := 0; i < lenA; i++ { 555 iteA = valA.Index(i).Interface() 556 chkRes = false 557 558 for _, k := range valB.MapKeys() { 559 chkKey = isInt(k.Interface()) && toInt(k.Interface()) == i 560 chkVal = reflect.DeepEqual(iteA, valB.MapIndex(k).Interface()) 561 562 if compareType == COMPARE_ONLY_KEY && chkKey { 563 chkRes = true 564 break 565 } else if compareType == COMPARE_ONLY_VALUE && chkVal { 566 chkRes = true 567 break 568 } else if compareType == COMPARE_BOTH_KEYVALUE && (chkKey && chkVal) { 569 chkRes = true 570 break 571 } 572 } 573 574 if chkRes { 575 resMap[i] = iteA 576 } 577 } 578 } else if (typA == reflect.Map) && (typB == reflect.Array || typB == reflect.Slice) { 579 //A是字典,B是数组/切片 580 var kv int 581 for _, k := range valA.MapKeys() { 582 iteA = valA.MapIndex(k).Interface() 583 chkRes = false 584 585 if isInt(k.Interface()) { 586 kv = toInt(k.Interface()) 587 } else { 588 kv = -1 589 } 590 591 if compareType == COMPARE_BOTH_KEYVALUE { 592 if kv >= 0 && kv < lenB { 593 chkRes = reflect.DeepEqual(iteA, valB.Index(kv).Interface()) 594 } 595 } else if compareType == COMPARE_ONLY_KEY { 596 chkRes = kv >= 0 && kv < lenB 597 } else if compareType == COMPARE_ONLY_VALUE { 598 for i := 0; i < lenB; i++ { 599 chkRes = reflect.DeepEqual(iteA, valB.Index(i).Interface()) 600 if chkRes { 601 break 602 } 603 } 604 } 605 606 if chkRes { 607 resMap[k.Interface()] = iteA 608 } 609 } 610 } else if (typA == reflect.Map) && (typB == reflect.Map) { 611 //两者都是字典 612 var kv string 613 for _, k := range valA.MapKeys() { 614 iteA = valA.MapIndex(k).Interface() 615 chkRes = false 616 kv = toStr(k.Interface()) 617 618 for _, k2 := range valB.MapKeys() { 619 chkKey = kv == toStr(k2.Interface()) 620 chkVal = reflect.DeepEqual(iteA, valB.MapIndex(k2).Interface()) 621 622 if compareType == COMPARE_ONLY_KEY && chkKey { 623 chkRes = true 624 break 625 } else if compareType == COMPARE_ONLY_VALUE && chkVal { 626 chkRes = true 627 break 628 } else if compareType == COMPARE_BOTH_KEYVALUE && (chkKey && chkVal) { 629 chkRes = true 630 break 631 } 632 } 633 634 if chkRes { 635 resMap[k.Interface()] = iteA 636 } 637 } 638 } 639 640 return resMap 641 } 642 643 // ArrayUnique 移除数组(切片/字典)中重复的值,返回字典,保留键名. 644 func (ka *LkkArray) ArrayUnique(arr interface{}) map[interface{}]interface{} { 645 var item interface{} 646 var str, key string 647 val := reflect.ValueOf(arr) 648 chkMp := make(map[string]interface{}) 649 res := make(map[interface{}]interface{}) 650 switch val.Kind() { 651 case reflect.Array, reflect.Slice: 652 for i := 0; i < val.Len(); i++ { 653 item = val.Index(i).Interface() 654 str = fmt.Sprintf("%+v", item) 655 key = string(md5Byte([]byte(str), 32)) 656 if _, ok := chkMp[key]; !ok { 657 chkMp[key] = true 658 res[i] = item 659 } 660 } 661 case reflect.Map: 662 for _, k := range val.MapKeys() { 663 item = val.MapIndex(k).Interface() 664 str = fmt.Sprintf("%+v", item) 665 key = string(md5Byte([]byte(str), 32)) 666 if _, ok := chkMp[key]; !ok { 667 chkMp[key] = true 668 res[reflect2Itf(k)] = item 669 } 670 } 671 default: 672 panic("[ArrayUnique]`arr type must be array|slice|map; but : " + val.Kind().String()) 673 } 674 675 return res 676 } 677 678 // ArraySearchItem 从数组(切片/字典)中搜索对应元素(单个). 679 // arr为要查找的数组,元素必须为字典/结构体;condition为条件字典. 680 func (ka *LkkArray) ArraySearchItem(arr interface{}, condition map[string]interface{}) (res interface{}) { 681 val := reflect.ValueOf(arr) 682 typ := val.Kind() 683 if typ != reflect.Array && typ != reflect.Slice && typ != reflect.Map { 684 panic("[ArraySearchItem]`arr type must be array|slice|map; but : " + typ.String()) 685 } 686 687 // 条件为空 688 if len(condition) == 0 { 689 return 690 } 691 692 switch typ { 693 case reflect.Array, reflect.Slice: 694 for i := 0; i < val.Len(); i++ { 695 res = compareConditionMap(condition, val.Index(i).Interface()) 696 if res != nil { 697 return 698 } 699 } 700 case reflect.Map: 701 for _, k := range val.MapKeys() { 702 res = compareConditionMap(condition, val.MapIndex(k).Interface()) 703 if res != nil { 704 return 705 } 706 } 707 } 708 709 return 710 } 711 712 // ArraySearchMutil 从数组(切片/字典)中搜索对应元素(多个). 713 // arr为要查找的数组,元素必须为字典/结构体;condition为条件字典. 714 func (ka *LkkArray) ArraySearchMutil(arr interface{}, condition map[string]interface{}) (res []interface{}) { 715 val := reflect.ValueOf(arr) 716 typ := val.Kind() 717 if typ != reflect.Array && typ != reflect.Slice && typ != reflect.Map { 718 panic("[ArraySearchMutil]`arr type must be array|slice|map; but : " + typ.String()) 719 } 720 721 // 条件为空 722 if len(condition) == 0 { 723 return 724 } 725 726 var item interface{} 727 switch typ { 728 case reflect.Array, reflect.Slice: 729 for i := 0; i < val.Len(); i++ { 730 item = compareConditionMap(condition, val.Index(i).Interface()) 731 if item != nil { 732 res = append(res, item) 733 } 734 } 735 case reflect.Map: 736 for _, k := range val.MapKeys() { 737 item = compareConditionMap(condition, val.MapIndex(k).Interface()) 738 if item != nil { 739 res = append(res, item) 740 } 741 } 742 } 743 744 return 745 } 746 747 // ArrayShuffle 打乱数组/切片排序. 748 func (ka *LkkArray) ArrayShuffle(arr interface{}) []interface{} { 749 val := reflect.ValueOf(arr) 750 typ := val.Kind() 751 if typ != reflect.Array && typ != reflect.Slice { 752 panic("[ArrayShuffle]`arr type must be array|slice; but : " + typ.String()) 753 } 754 755 num := val.Len() 756 res := make([]interface{}, num) 757 758 for i := 0; i < num; i++ { 759 res[i] = val.Index(i).Interface() 760 } 761 762 r := rand.New(rand.NewSource(time.Now().UnixNano())) 763 r.Shuffle(num, func(i, j int) { 764 res[i], res[j] = res[j], res[i] 765 }) 766 767 return res 768 } 769 770 // IsEqualArray 两个数组/切片是否相同(不管元素顺序),且不会检查元素类型; 771 // arr1, arr2 是要比较的数组/切片. 772 func (ka *LkkArray) IsEqualArray(arr1, arr2 interface{}) bool { 773 valA := reflect.ValueOf(arr1) 774 valB := reflect.ValueOf(arr2) 775 typA := valA.Kind() 776 typB := valB.Kind() 777 778 if (typA != reflect.Array && typA != reflect.Slice) || (typB != reflect.Array && typB != reflect.Slice) { 779 panic("[IsEqualArray]`arr1,arr2 type must be array|slice; but : " + typA.String() + "/" + typB.String()) 780 } 781 782 length := valA.Len() 783 if length != valB.Len() { 784 return false 785 } 786 787 var itmAStr, itmBstr string 788 var format string = "%#v" 789 expectedMap := make(map[string]bool) 790 actualMap := make(map[string]bool) 791 for i := 0; i < length; i++ { 792 itmAStr = fmt.Sprintf(format, valA.Index(i).Interface()) 793 itmBstr = fmt.Sprintf(format, valB.Index(i).Interface()) 794 expectedMap[itmAStr] = true 795 actualMap[itmBstr] = true 796 } 797 798 return reflect.DeepEqual(expectedMap, actualMap) 799 } 800 801 // IsEqualMap 两个字典是否相同(不管键顺序),且不会严格检查元素类型; 802 // arr1, arr2 是要比较的字典. 803 func (ka *LkkArray) IsEqualMap(arr1, arr2 interface{}) bool { 804 valA := reflect.ValueOf(arr1) 805 valB := reflect.ValueOf(arr2) 806 typA := valA.Kind() 807 typB := valB.Kind() 808 809 if typA != reflect.Map || typB != reflect.Map { 810 panic("[IsEqualMap]`arr1,arr2 type must be array|slice; but : " + typA.String() + "/" + typB.String()) 811 } 812 813 length := valA.Len() 814 if length != valB.Len() { 815 return false 816 } 817 818 var key string 819 expectedMap := make(map[string]interface{}) 820 actualMap := make(map[string]interface{}) 821 822 for _, k := range valA.MapKeys() { 823 key = fmt.Sprintf("%v", k) 824 expectedMap[key] = fmt.Sprintf("%#v", valA.MapIndex(k).Interface()) 825 } 826 for _, k := range valB.MapKeys() { 827 key = fmt.Sprintf("%v", k) 828 actualMap[key] = fmt.Sprintf("%#v", valB.MapIndex(k).Interface()) 829 } 830 831 return reflect.DeepEqual(expectedMap, actualMap) 832 } 833 834 // Length 获取数组/切片的长度;结果为-1表示变量不是数组或切片. 835 func (ka *LkkArray) Length(val interface{}) int { 836 return lenArrayOrSlice(val, 3) 837 } 838 839 // IsArray 变量是否数组. 840 func (ka *LkkArray) IsArray(val interface{}) bool { 841 l := lenArrayOrSlice(val, 1) 842 return l >= 0 843 } 844 845 // IsSlice 变量是否切片. 846 func (ka *LkkArray) IsSlice(val interface{}) bool { 847 l := lenArrayOrSlice(val, 2) 848 return l >= 0 849 } 850 851 // IsArrayOrSlice 变量是否数组或切片. 852 func (ka *LkkArray) IsArrayOrSlice(val interface{}) bool { 853 l := lenArrayOrSlice(val, 3) 854 return l >= 0 855 } 856 857 // IsMap 变量是否字典. 858 func (ka *LkkArray) IsMap(val interface{}) bool { 859 return isMap(val) 860 } 861 862 // IsStruct 变量是否结构体. 863 func (ka *LkkArray) IsStruct(val interface{}) bool { 864 return isStruct(val) 865 } 866 867 // DeleteSliceItems 删除数组/切片的元素,返回一个新切片. 868 // ids为多个元素的索引(0~len(val)-1); 869 // del为删除元素的数量. 870 func (ka *LkkArray) DeleteSliceItems(val interface{}, ids ...int) (res []interface{}, del int) { 871 sl := reflect.ValueOf(val) 872 styp := sl.Kind() 873 874 if styp != reflect.Array && styp != reflect.Slice { 875 panic("[DeleteSliceItems]`val type must be array|slice") 876 } 877 878 slen := sl.Len() 879 if slen == 0 { 880 return 881 } 882 883 var item interface{} 884 var chk bool 885 for i := 0; i < slen; i++ { 886 item = sl.Index(i).Interface() 887 chk = true 888 889 for _, v := range ids { 890 if i == v { 891 del++ 892 chk = false 893 break 894 } 895 } 896 897 if chk { 898 res = append(res, item) 899 } 900 } 901 902 return 903 } 904 905 // InArray 元素needle是否在数组haystack(切片/字典)内. 906 func (ka *LkkArray) InArray(needle interface{}, haystack interface{}) bool { 907 val := reflect.ValueOf(haystack) 908 switch val.Kind() { 909 case reflect.Array, reflect.Slice: 910 for i := 0; i < val.Len(); i++ { 911 if reflect.DeepEqual(needle, val.Index(i).Interface()) { 912 return true 913 } 914 } 915 case reflect.Map: 916 for _, k := range val.MapKeys() { 917 if reflect.DeepEqual(needle, val.MapIndex(k).Interface()) { 918 return true 919 } 920 } 921 default: 922 panic("[InArray]`haystack type must be array|slice|map") 923 } 924 925 return false 926 } 927 928 // InIntSlice 是否在整型切片内. 929 func (ka *LkkArray) InIntSlice(i int, list []int) bool { 930 for _, item := range list { 931 if item == i { 932 return true 933 } 934 } 935 return false 936 } 937 938 // InInt64Slice 是否在64位整型切片内. 939 func (ka *LkkArray) InInt64Slice(i int64, list []int64) bool { 940 for _, item := range list { 941 if item == i { 942 return true 943 } 944 } 945 return false 946 } 947 948 // InStringSlice 是否在字符串切片内. 949 func (ka *LkkArray) InStringSlice(str string, list []string) bool { 950 for _, item := range list { 951 if item == str { 952 return true 953 } 954 } 955 return false 956 } 957 958 // SliceFill 用给定的值val填充切片,num为插入元素的数量. 959 func (ka *LkkArray) SliceFill(val interface{}, num int) []interface{} { 960 if num <= 0 { 961 return nil 962 } 963 964 var res = make([]interface{}, num) 965 for i := 0; i < num; i++ { 966 res[i] = val 967 } 968 969 return res 970 } 971 972 // ArrayFlip 交换数组(切片/字典)中的键和值. 973 func (ka *LkkArray) ArrayFlip(arr interface{}) map[interface{}]interface{} { 974 res := make(map[interface{}]interface{}) 975 val := reflect.ValueOf(arr) 976 var key interface{} 977 switch val.Kind() { 978 case reflect.Array, reflect.Slice: 979 for i := 0; i < val.Len(); i++ { 980 key = val.Index(i).Interface() 981 if key != nil && fmt.Sprintf("%v", key) != "" { 982 res[key] = i 983 } 984 } 985 case reflect.Map: 986 for _, k := range val.MapKeys() { 987 key = val.MapIndex(k).Interface() 988 if key != nil && fmt.Sprintf("%v", key) != "" { 989 res[key] = k 990 } 991 } 992 default: 993 panic("[ArrayFlip]`arr type must be array|slice|map") 994 } 995 996 return res 997 } 998 999 // MergeSlice 合并一个或多个数组/切片. 1000 // filterZero 是否过滤零值元素(nil,false,0,'',[]),true时排除零值元素,false时保留零值元素. 1001 // ss是元素为数组/切片的切片. 1002 func (ka *LkkArray) MergeSlice(filterZero bool, ss ...interface{}) []interface{} { 1003 var res []interface{} 1004 switch len(ss) { 1005 case 0: 1006 break 1007 default: 1008 n := 0 1009 for i, v := range ss { 1010 chkLen := lenArrayOrSlice(v, 3) 1011 if chkLen == -1 { 1012 msg := fmt.Sprintf("[MergeSlice]`ss type must be array|slice, but [%d]th item not is.", i) 1013 panic(msg) 1014 } else { 1015 n += chkLen 1016 } 1017 } 1018 res = make([]interface{}, 0, n) 1019 var item interface{} 1020 for _, v := range ss { 1021 val := reflect.ValueOf(v) 1022 switch val.Kind() { 1023 case reflect.Array, reflect.Slice: 1024 for i := 0; i < val.Len(); i++ { 1025 item = val.Index(i).Interface() 1026 if !filterZero || (filterZero && !val.Index(i).IsZero()) { 1027 res = append(res, item) 1028 } 1029 } 1030 } 1031 } 1032 } 1033 1034 return res 1035 } 1036 1037 // MergeMap 合并字典,相同的键名时,后面的值将覆盖前一个值. 1038 // ss是元素为字典的切片. 1039 func (ka *LkkArray) MergeMap(ss ...interface{}) map[interface{}]interface{} { 1040 res := make(map[interface{}]interface{}) 1041 switch len(ss) { 1042 case 0: 1043 break 1044 default: 1045 for i, v := range ss { 1046 val := reflect.ValueOf(v) 1047 switch val.Kind() { 1048 case reflect.Map: 1049 for _, k := range val.MapKeys() { 1050 res[reflect2Itf(k)] = val.MapIndex(k).Interface() 1051 } 1052 default: 1053 panic(fmt.Sprintf("[MergeMap]`ss type must be map, but [%d]th item not is.", i)) 1054 } 1055 } 1056 } 1057 return res 1058 } 1059 1060 // ArrayPad 以指定长度将一个值item填充进arr数组/切片. 1061 // 若 size 为正,则填补到数组的右侧,如果为负则从左侧开始填补; 1062 // 若 size 的绝对值小于或等于 arr 数组的长度则没有任何填补. 1063 func (ka *LkkArray) ArrayPad(arr interface{}, size int, item interface{}) []interface{} { 1064 val := reflect.ValueOf(arr) 1065 switch val.Kind() { 1066 case reflect.Array, reflect.Slice: 1067 length := val.Len() 1068 if length == 0 && size > 0 { 1069 return ka.SliceFill(item, size) 1070 } 1071 1072 orig := make([]interface{}, length) 1073 for i := 0; i < length; i++ { 1074 orig[i] = val.Index(i).Interface() 1075 } 1076 1077 if size == 0 || (size > 0 && size < length) || (size < 0 && size > -length) { 1078 return orig 1079 } 1080 1081 n := size 1082 if size < 0 { 1083 n = -size 1084 } 1085 n -= length 1086 items := make([]interface{}, n) 1087 for i := 0; i < n; i++ { 1088 items[i] = item 1089 } 1090 1091 if size > 0 { 1092 return append(orig, items...) 1093 } 1094 return append(items, orig...) 1095 default: 1096 panic("[ArrayPad]`arr type must be array|slice") 1097 } 1098 } 1099 1100 // ArrayRand 从数组(切片/字典)中随机取出num个元素. 1101 func (ka *LkkArray) ArrayRand(arr interface{}, num int) []interface{} { 1102 val := reflect.ValueOf(arr) 1103 typ := val.Kind() 1104 if typ != reflect.Array && typ != reflect.Slice && typ != reflect.Map { 1105 panic("[ArrayRand]`arr type must be array|slice|map") 1106 } 1107 if num < 1 { 1108 panic("[ArrayRand]`num cannot be less than 1") 1109 } 1110 1111 length := val.Len() 1112 if length == 0 { 1113 return nil 1114 } 1115 if num > length { 1116 num = length 1117 } 1118 res := make([]interface{}, num) 1119 r := rand.New(rand.NewSource(time.Now().UnixNano())) 1120 1121 switch typ { 1122 case reflect.Array, reflect.Slice: 1123 for i, v := range r.Perm(length) { 1124 if i < num { 1125 res[i] = val.Index(v).Interface() 1126 } else { 1127 break 1128 } 1129 } 1130 case reflect.Map: 1131 var ks []reflect.Value 1132 for _, k := range val.MapKeys() { 1133 ks = append(ks, k) 1134 } 1135 for i, v := range r.Perm(length) { 1136 if i < num { 1137 res[i] = val.MapIndex(ks[v]).Interface() 1138 } else { 1139 break 1140 } 1141 } 1142 } 1143 1144 return res 1145 } 1146 1147 // CutSlice 裁剪切片,返回根据offset(起始位置)和size(数量)参数所指定的arr(数组/切片)中的一段切片. 1148 func (ka *LkkArray) CutSlice(arr interface{}, offset, size int) []interface{} { 1149 if size < 1 { 1150 panic("[CutSlice]`size cannot be less than 1") 1151 } 1152 1153 val := reflect.ValueOf(arr) 1154 switch val.Kind() { 1155 case reflect.Array, reflect.Slice: 1156 length := val.Len() 1157 if length == 0 || (offset > 0 && offset > length-1) { 1158 return nil 1159 } 1160 1161 items := make([]interface{}, length) 1162 for i := 0; i < val.Len(); i++ { 1163 items[i] = val.Index(i).Interface() 1164 } 1165 1166 if offset < 0 { 1167 offset = offset%length + length 1168 } 1169 end := offset + size 1170 if end < length { 1171 return items[offset:end] 1172 } 1173 return items[offset:] 1174 default: 1175 panic("[CutSlice]`arr type must be array|slice") 1176 } 1177 } 1178 1179 // NewStrMapItf 新建[字符-接口]字典. 1180 func (ka *LkkArray) NewStrMapItf() map[string]interface{} { 1181 return make(map[string]interface{}) 1182 } 1183 1184 // NewStrMapStr 新建[字符-字符]字典. 1185 func (ka *LkkArray) NewStrMapStr() map[string]string { 1186 return make(map[string]string) 1187 }