github.com/Aoi-hosizora/ahlib@v1.5.1-0.20230404072829-241b93cf91c7/xslice/xslice.go (about) 1 package xslice 2 3 import ( 4 "math/rand" 5 "sort" 6 "time" 7 ) 8 9 // Equaller represents an equality function for two interface{} values, is used in XXXWith methods. 10 type Equaller func(i, j interface{}) bool 11 12 // Lesser represents a less function for sort, see sort.Interface. 13 type Lesser func(i, j interface{}) bool 14 15 // defaultEqualler represents a default Equaller, it just checks equality by `==`. 16 var defaultEqualler Equaller = func(i, j interface{}) bool { 17 return i == j 18 } 19 20 // ShuffleSelf shuffles the []interface{} slice, by modifying given slice directly. 21 func ShuffleSelf(slice []interface{}) { 22 coreShuffle(checkInterfaceSliceParam(slice)) 23 } 24 25 // Shuffle shuffles the []interface{} slice and returns the result. 26 func Shuffle(slice []interface{}) []interface{} { 27 newSlice := cloneInterfaceSlice(slice) 28 coreShuffle(checkInterfaceSliceParam(newSlice)) 29 return newSlice 30 } 31 32 // ShuffleSelfG shuffles the []T slice, by modifying given slice directly, is the generic function of ShuffleSelf. 33 func ShuffleSelfG(slice interface{}) { 34 coreShuffle(checkSliceInterfaceParam(slice)) 35 } 36 37 // ShuffleG shuffles the []T slice and returns the result, is the generic function of Shuffle. 38 func ShuffleG(slice interface{}) interface{} { 39 newSlice := cloneSliceInterface(slice) 40 coreShuffle(checkSliceInterfaceParam(newSlice)) 41 return newSlice 42 } 43 44 func init() { 45 // for coreShuffle 46 rand.Seed(time.Now().UnixNano()) 47 } 48 49 // coreShuffle is the implementation for ShuffleSelf, Shuffle, ShuffleSelfG and ShuffleG. 50 func coreShuffle(slice innerSlice) { 51 for i := slice.length() - 1; i > 0; i-- { 52 j := rand.Intn(i + 1) 53 itemI, itemJ := slice.get(i), slice.get(j) 54 slice.set(i, itemJ) 55 slice.set(j, itemI) 56 } 57 } 58 59 // ReverseSelf reverses the []interface{} slice, by modifying given slice directly. 60 func ReverseSelf(slice []interface{}) { 61 coreReverse(checkInterfaceSliceParam(slice)) 62 } 63 64 // Reverse reverses the []interface{} slice and returns the result. 65 func Reverse(slice []interface{}) []interface{} { 66 newSlice := cloneInterfaceSlice(slice) 67 coreReverse(checkInterfaceSliceParam(newSlice)) 68 return newSlice 69 } 70 71 // ReverseSelfG reverses the []T slice, by modifying given slice directly, is the generic function of ReverseSelf. 72 func ReverseSelfG(slice interface{}) { 73 coreReverse(checkSliceInterfaceParam(slice)) 74 } 75 76 // ReverseG reverses the []T slice and returns the result, is the generic function of Reverse. 77 func ReverseG(slice interface{}) interface{} { 78 newSlice := cloneSliceInterface(slice) 79 coreReverse(checkSliceInterfaceParam(newSlice)) 80 return newSlice 81 } 82 83 // coreReverse is the implementation for ReverseSelf Reverse, ReverseSelfG and ReverseG. 84 func coreReverse(slice innerSlice) { 85 for i, j := 0, slice.length()-1; i < j; i, j = i+1, j-1 { 86 itemI, itemJ := slice.get(i), slice.get(j) 87 slice.set(i, itemJ) 88 slice.set(j, itemI) 89 } 90 } 91 92 // SortSelf sorts the []interface{} slice with less function, by modifying given slice directly. 93 func SortSelf(slice []interface{}, less Lesser) { 94 coreSort(checkInterfaceSliceParam(slice), less, false) 95 } 96 97 // Sort sorts the []interface{} slice with less function and returns the result. 98 func Sort(slice []interface{}, less Lesser) []interface{} { 99 newSlice := cloneInterfaceSlice(slice) 100 coreSort(checkInterfaceSliceParam(newSlice), less, false) 101 return newSlice 102 } 103 104 // SortSelfG sorts the []T slice with less function, by modifying given slice directly, is the generic function of SortSelf. 105 func SortSelfG(slice interface{}, less Lesser) { 106 coreSort(checkSliceInterfaceParam(slice), less, false) 107 } 108 109 // SortG sorts the []T slice with less function and returns the result, is the generic function of Sort. 110 func SortG(slice interface{}, less Lesser) interface{} { 111 newSlice := cloneSliceInterface(slice) 112 coreSort(checkSliceInterfaceParam(newSlice), less, false) 113 return newSlice 114 } 115 116 // StableSortSelf sorts the []interface{} slice in stable with less function, by modifying given slice directly. 117 func StableSortSelf(slice []interface{}, less Lesser) { 118 coreSort(checkInterfaceSliceParam(slice), less, true) 119 } 120 121 // StableSort sorts the []interface{} slice in stable with less function and returns the result. 122 func StableSort(slice []interface{}, less Lesser) []interface{} { 123 newSlice := cloneInterfaceSlice(slice) 124 coreSort(checkInterfaceSliceParam(newSlice), less, true) 125 return newSlice 126 } 127 128 // StableSortSelfG sorts the []T slice in stable with less function, by modifying given slice directly, is the generic function of StableSortSelf. 129 func StableSortSelfG(slice interface{}, less Lesser) { 130 coreSort(checkSliceInterfaceParam(slice), less, true) 131 } 132 133 // StableSortG sorts the []T slice with in stable less function and returns the result, is the generic function of StableSort. 134 func StableSortG(slice interface{}, less Lesser) interface{} { 135 newSlice := cloneSliceInterface(slice) 136 coreSort(checkSliceInterfaceParam(newSlice), less, true) 137 return newSlice 138 } 139 140 // coreSort is the implementation for SortSelf, Sort, StableSortSelf, StableSort, SortSelfG, SortG, StableSortSelfG and StableSortG, using sort.Slice and sort.SliceStable. 141 func coreSort(slice innerSlice, less Lesser, stable bool) { 142 ss := &sortableSlice{slice: slice, less: less} 143 if stable { 144 sort.Stable(ss) 145 } else { 146 sort.Sort(ss) 147 } 148 } 149 150 // IndexOf returns the first index of value in the []interface{} slice. 151 func IndexOf(slice []interface{}, value interface{}) int { 152 return coreIndexOf(checkInterfaceSliceParam(slice), value, defaultEqualler) 153 } 154 155 // IndexOfWith returns the first index of value in the []interface{} slice with Equaller. 156 func IndexOfWith(slice []interface{}, value interface{}, equaller Equaller) int { 157 return coreIndexOf(checkInterfaceSliceParam(slice), value, equaller) 158 } 159 160 // IndexOfG returns the first index of value in the []T slice, is the generic function of IndexOf. 161 func IndexOfG(slice interface{}, value interface{}) int { 162 s, v := checkSliceInterfaceAndElemParam(slice, value) 163 return coreIndexOf(s, v, defaultEqualler) 164 } 165 166 // IndexOfWithG returns the first index of value in the []T slice with Equaller, is the generic function of IndexOfWith. 167 func IndexOfWithG(slice interface{}, value interface{}, equaller Equaller) int { 168 s, v := checkSliceInterfaceAndElemParam(slice, value) 169 return coreIndexOf(s, v, equaller) 170 } 171 172 // coreIndexOf is the implementation for IndexOf, IndexOfWith, IndexOfG and IndexOfWithG. 173 func coreIndexOf(slice innerSlice, value interface{}, equaller Equaller) int { 174 length := slice.length() 175 for idx := 0; idx < length; idx++ { 176 item := slice.get(idx) 177 if equaller(item, value) { 178 return idx 179 } 180 } 181 return -1 182 } 183 184 // LastIndexOf returns the last index of value in the []interface{} slice. 185 func LastIndexOf(slice []interface{}, value interface{}) int { 186 return coreLastIndexOf(checkInterfaceSliceParam(slice), value, defaultEqualler) 187 } 188 189 // LastIndexOfWith returns the last index of value in the []interface{} slice with Equaller. 190 func LastIndexOfWith(slice []interface{}, value interface{}, equaller Equaller) int { 191 return coreLastIndexOf(checkInterfaceSliceParam(slice), value, equaller) 192 } 193 194 // LastIndexOfG returns the last index of value in the []T slice, is the generic function of IndexOf. 195 func LastIndexOfG(slice interface{}, value interface{}) int { 196 s, v := checkSliceInterfaceAndElemParam(slice, value) 197 return coreLastIndexOf(s, v, defaultEqualler) 198 } 199 200 // LastIndexOfWithG returns the last index of value in the []T slice with Equaller, is the generic function of IndexOfWith. 201 func LastIndexOfWithG(slice interface{}, value interface{}, equaller Equaller) int { 202 s, v := checkSliceInterfaceAndElemParam(slice, value) 203 return coreLastIndexOf(s, v, equaller) 204 } 205 206 // coreLastIndexOf is the implementation for LastIndexOf, LastIndexOfWith, LastIndexOfG and LastIndexOfWithG. 207 func coreLastIndexOf(slice innerSlice, value interface{}, equaller Equaller) int { 208 for idx := slice.length() - 1; idx >= 0; idx-- { 209 item := slice.get(idx) 210 if equaller(item, value) { 211 return idx 212 } 213 } 214 return -1 215 } 216 217 // Contains returns true if value is in the []interface{} slice. 218 func Contains(slice []interface{}, value interface{}) bool { 219 return coreContains(checkInterfaceSliceParam(slice), value, defaultEqualler) 220 } 221 222 // ContainsWith returns true if value is in the []interface{} slice with Equaller. 223 func ContainsWith(slice []interface{}, value interface{}, equaller Equaller) bool { 224 return coreContains(checkInterfaceSliceParam(slice), value, equaller) 225 } 226 227 // ContainsG returns true if value is in the []T slice, is the generic function of Contains. 228 func ContainsG(slice interface{}, value interface{}) bool { 229 s, v := checkSliceInterfaceAndElemParam(slice, value) 230 return coreContains(s, v, defaultEqualler) 231 } 232 233 // ContainsWithG returns true if value is in the []T slice with Equaller, is the generic function of ContainsWith. 234 func ContainsWithG(slice interface{}, value interface{}, equaller Equaller) bool { 235 s, v := checkSliceInterfaceAndElemParam(slice, value) 236 return coreContains(s, v, equaller) 237 } 238 239 // coreContains is the implementation for Contains, ContainsWith, ContainsG and ContainsWithG. 240 func coreContains(slice innerSlice, value interface{}, equaller Equaller) bool { 241 length := slice.length() 242 for idx := 0; idx < length; idx++ { 243 item := slice.get(idx) 244 if equaller(item, value) { 245 return true 246 } 247 } 248 return false 249 } 250 251 // Count returns the count of value in the []interface{} slice. 252 func Count(slice []interface{}, value interface{}) int { 253 return coreCount(checkInterfaceSliceParam(slice), value, defaultEqualler) 254 } 255 256 // CountWith returns the count of value in the []interface{} slice with Equaller. 257 func CountWith(slice []interface{}, value interface{}, equaller Equaller) int { 258 return coreCount(checkInterfaceSliceParam(slice), value, equaller) 259 } 260 261 // CountG returns the count of value in the []T slice, is the generic function of Count. 262 func CountG(slice interface{}, value interface{}) int { 263 s, v := checkSliceInterfaceAndElemParam(slice, value) 264 return coreCount(s, v, defaultEqualler) 265 } 266 267 // CountWithG returns the count of value in the []T slice with Equaller, is the generic function of CountWith. 268 func CountWithG(slice interface{}, value interface{}, equaller Equaller) int { 269 s, v := checkSliceInterfaceAndElemParam(slice, value) 270 return coreCount(s, v, equaller) 271 } 272 273 // coreCount is the implementation for Count, CountWith, CountG and CountWithG. 274 func coreCount(slice innerSlice, value interface{}, equaller Equaller) int { 275 cnt := 0 276 length := slice.length() 277 for idx := 0; idx < length; idx++ { 278 item := slice.get(idx) 279 if equaller(item, value) { 280 cnt++ 281 } 282 } 283 return cnt 284 } 285 286 // Insert inserts values into []interface{} slice at index position using a new slice space to store. 287 func Insert(slice []interface{}, index int, values ...interface{}) []interface{} { 288 return coreInsert(checkInterfaceSliceParam(slice), checkInterfaceSliceParam(values), index, false).actual().([]interface{}) 289 } 290 291 // InsertSelf inserts values into []interface{} slice at index position using the space of given slice. 292 func InsertSelf(slice []interface{}, index int, values ...interface{}) []interface{} { 293 return coreInsert(checkInterfaceSliceParam(slice), checkInterfaceSliceParam(values), index, true).actual().([]interface{}) 294 } 295 296 // InsertG inserts values into []T slice at index position using a new slice space to store, is the generic function of Insert. 297 func InsertG(slice interface{}, index int, values ...interface{}) interface{} { 298 s, v := checkTwoSliceInterfaceParam(slice, cloneSliceInterfaceFromInterfaceSlice(values, slice)) 299 return coreInsert(s, v, index, false).actual() 300 } 301 302 // InsertSelfG inserts values into []T slice at index position using the space of given slice, is the generic function of InsertSelf. 303 func InsertSelfG(slice interface{}, index int, values ...interface{}) interface{} { 304 s, v := checkTwoSliceInterfaceParam(slice, cloneSliceInterfaceFromInterfaceSlice(values, slice)) 305 return coreInsert(s, v, index, true).actual() 306 } 307 308 // coreInsert is the implementation for InsertSelf, Insert, InsertSelfG and InsertG. 309 func coreInsert(slice, values innerSlice, index int, self bool) innerSlice { 310 if values.length() == 0 { 311 if self { 312 return slice 313 } 314 return cloneInnerSliceItems(slice, 0) 315 } 316 if self { 317 slice.insert(index, values) 318 return slice 319 } 320 newSlice := cloneInnerSliceItems(slice, values.length()) 321 newSlice.insert(index, values) 322 return newSlice 323 } 324 325 // Delete deletes value from []interface{} slice in n times. 326 func Delete(slice []interface{}, value interface{}, n int) []interface{} { 327 return coreDelete(checkInterfaceSliceParam(slice), value, n, defaultEqualler).actual().([]interface{}) 328 } 329 330 // DeleteWith deletes value from []interface{} slice in n times with Equaller. 331 func DeleteWith(slice []interface{}, value interface{}, n int, equaller Equaller) []interface{} { 332 return coreDelete(checkInterfaceSliceParam(slice), value, n, equaller).actual().([]interface{}) 333 } 334 335 // DeleteG deletes value from []T slice in n times, is the generic function of Delete. 336 func DeleteG(slice interface{}, value interface{}, n int) interface{} { 337 s, v := checkSliceInterfaceAndElemParam(slice, value) 338 return coreDelete(s, v, n, defaultEqualler).actual() 339 } 340 341 // DeleteWithG deletes value from []T slice in n times with Equaller, is the generic function of DeleteWith. 342 func DeleteWithG(slice interface{}, value interface{}, n int, equaller Equaller) interface{} { 343 s, v := checkSliceInterfaceAndElemParam(slice, value) 344 return coreDelete(s, v, n, equaller).actual() 345 } 346 347 // DeleteAll deletes value from []interface{} slice in all. 348 func DeleteAll(slice []interface{}, value interface{}) []interface{} { 349 return coreDelete(checkInterfaceSliceParam(slice), value, 0, defaultEqualler).actual().([]interface{}) 350 } 351 352 // DeleteAllWith deletes value from []interface{} slice in all with Equaller. 353 func DeleteAllWith(slice []interface{}, value interface{}, equaller Equaller) []interface{} { 354 return coreDelete(checkInterfaceSliceParam(slice), value, 0, equaller).actual().([]interface{}) 355 } 356 357 // DeleteAllG deletes value from []T slice in all, is the generic function of DeleteAll. 358 func DeleteAllG(slice interface{}, value interface{}) interface{} { 359 s, v := checkSliceInterfaceAndElemParam(slice, value) 360 return coreDelete(s, v, 0, defaultEqualler).actual() 361 } 362 363 // DeleteAllWithG deletes value from []T slice in all with Equaller, is the generic function of DeleteAllWith. 364 func DeleteAllWithG(slice interface{}, value interface{}, equaller Equaller) interface{} { 365 s, v := checkSliceInterfaceAndElemParam(slice, value) 366 return coreDelete(s, v, 0, equaller).actual() 367 } 368 369 // coreDelete is the implementation for Delete, DeleteWith, DeleteAll, DeleteAllWith, DeleteG, DeleteWithG, DeleteAllG and DeleteAllWithG. 370 func coreDelete(slice innerSlice, value interface{}, n int, equaller Equaller) innerSlice { 371 length := slice.length() 372 if n <= 0 { 373 n = length 374 } 375 out := makeSameTypeInnerSlice(slice, 0, 0) 376 cnt := 0 377 for idx := 0; idx < length; idx++ { // O(n) 378 if cnt >= n { 379 for idx2 := idx; idx2 < length; idx2++ { 380 out.append(slice.get(idx2)) 381 } 382 break 383 } 384 item := slice.get(idx) 385 if equaller(item, value) { 386 cnt++ 387 } else { 388 out.append(item) 389 } 390 } 391 return out 392 } 393 394 // DeleteSelf deletes value from []interface{} slice in n times, by modifying given slice directly. 395 func DeleteSelf(slice []interface{}, value interface{}, n int) []interface{} { 396 return coreDeleteSelf(checkInterfaceSliceParam(slice), value, n, defaultEqualler).actual().([]interface{}) 397 } 398 399 // DeleteSelfWith deletes value from []interface{} slice in n times with Equaller, by modifying given slice directly. 400 func DeleteSelfWith(slice []interface{}, value interface{}, n int, equaller Equaller) []interface{} { 401 return coreDeleteSelf(checkInterfaceSliceParam(slice), value, n, equaller).actual().([]interface{}) 402 } 403 404 // DeleteSelfG deletes value from []T slice in n times, by modifying given slice directly, is the generic function of DeleteSelf. 405 func DeleteSelfG(slice interface{}, value interface{}, n int) interface{} { 406 s, v := checkSliceInterfaceAndElemParam(slice, value) 407 return coreDeleteSelf(s, v, n, defaultEqualler).actual() 408 } 409 410 // DeleteSelfWithG deletes value from []T slice in n times with Equaller, by modifying given slice directly, is the generic function of DeleteSelfWith. 411 func DeleteSelfWithG(slice interface{}, value interface{}, n int, equaller Equaller) interface{} { 412 s, v := checkSliceInterfaceAndElemParam(slice, value) 413 return coreDeleteSelf(s, v, n, equaller).actual() 414 } 415 416 // DeleteAllSelf deletes value from []interface{} slice in all, by modifying given slice directly. 417 func DeleteAllSelf(slice []interface{}, value interface{}) []interface{} { 418 return coreDeleteSelf(checkInterfaceSliceParam(slice), value, 0, defaultEqualler).actual().([]interface{}) 419 } 420 421 // DeleteAllSelfWith deletes value from []interface{} slice in all with Equaller, by modifying given slice directly. 422 func DeleteAllSelfWith(slice []interface{}, value interface{}, equaller Equaller) []interface{} { 423 return coreDeleteSelf(checkInterfaceSliceParam(slice), value, 0, equaller).actual().([]interface{}) 424 } 425 426 // DeleteAllSelfG deletes value from []T slice in all, by modifying given slice directly, is the generic function of DeleteAll. 427 func DeleteAllSelfG(slice interface{}, value interface{}) interface{} { 428 s, v := checkSliceInterfaceAndElemParam(slice, value) 429 return coreDeleteSelf(s, v, 0, defaultEqualler).actual() 430 } 431 432 // DeleteAllSelfWithG deletes value from []T slice in all with Equaller, by modifying given slice directly, is the generic function of DeleteAllWith. 433 func DeleteAllSelfWithG(slice interface{}, value interface{}, equaller Equaller) interface{} { 434 s, v := checkSliceInterfaceAndElemParam(slice, value) 435 return coreDeleteSelf(s, v, 0, equaller).actual() 436 } 437 438 // coreDeleteSelf is the implementation for DeleteSelf, DeleteSelfWith, DeleteAllSelf, DeleteAllSelfWith, DeleteSelfG, DeleteSelfWithG, DeleteAllSelfG and DeleteAllSelfWithG. 439 func coreDeleteSelf(slice innerSlice, value interface{}, n int, equaller Equaller) innerSlice { 440 if n <= 0 { 441 n = slice.length() 442 } 443 cnt := 0 444 idx := coreIndexOf(slice, value, equaller) 445 for idx != -1 && cnt < n { 446 slice.remove(idx) 447 cnt++ 448 idx = coreIndexOf(slice, value, equaller) // O(n^2) 449 } 450 return slice 451 } 452 453 // ContainsAll returns true if values in []interface{} subset are all in the []interface{} list. 454 func ContainsAll(list, subset []interface{}) bool { 455 return coreContainsAll(checkInterfaceSliceParam(list), checkInterfaceSliceParam(subset), defaultEqualler) 456 } 457 458 // ContainsAllWith returns true if values in []interface{} subset are all in the []interface{} list. 459 func ContainsAllWith(list, subset []interface{}, equaller Equaller) bool { 460 return coreContainsAll(checkInterfaceSliceParam(list), checkInterfaceSliceParam(subset), equaller) 461 } 462 463 // ContainsAllG returns true if values in []T subset are all in the []T list, is the generic function of ContainsAll. 464 func ContainsAllG(list, subset interface{}) bool { 465 s1, s2 := checkTwoSliceInterfaceParam(list, subset) 466 return coreContainsAll(s1, s2, defaultEqualler) 467 } 468 469 // ContainsAllWithG returns true if values in []T subset are all in the []T list, is the generic function of ContainsAllWith. 470 func ContainsAllWithG(list, subset interface{}, equaller Equaller) bool { 471 s1, s2 := checkTwoSliceInterfaceParam(list, subset) 472 return coreContainsAll(s1, s2, equaller) 473 } 474 475 // coreContainsAll is the implementation for ContainsAll, ContainsAllWith, ContainsAllG and ContainsAllWithG. 476 func coreContainsAll(list, subset innerSlice, equaller Equaller) bool { 477 for i := 0; i < subset.length(); i++ { 478 item := subset.get(i) 479 if !coreContains(list, item, equaller) { 480 return false 481 } 482 } 483 return true 484 } 485 486 // Diff returns the difference of two []interface{} slices. 487 func Diff(slice1, slice2 []interface{}) []interface{} { 488 return coreDiff(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), defaultEqualler).actual().([]interface{}) 489 } 490 491 // DiffWith returns the difference of two []interface{} slices with Equaller. 492 func DiffWith(slice1, slice2 []interface{}, equaller Equaller) []interface{} { 493 return coreDiff(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), equaller).actual().([]interface{}) 494 } 495 496 // DiffG returns the difference of two []T slices, is the generic function of Diff. 497 func DiffG(slice1, slice2 interface{}) interface{} { 498 s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2) 499 return coreDiff(s1, s2, defaultEqualler).actual() 500 } 501 502 // DiffWithG returns the difference of two []T slices with Equaller, is the generic function of DiffWith. 503 func DiffWithG(slice1, slice2 interface{}, equaller Equaller) interface{} { 504 s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2) 505 return coreDiff(s1, s2, equaller).actual() 506 } 507 508 // coreDiff is the implementation for Diff, DiffWith, DiffG and DiffWithG. 509 func coreDiff(slice1, slice2 innerSlice, equaller Equaller) innerSlice { 510 result := makeSameTypeInnerSlice(slice1, 0, 0) 511 length1 := slice1.length() 512 for i1 := 0; i1 < length1; i1++ { 513 item1 := slice1.get(i1) 514 if !coreContains(slice2, item1, equaller) { 515 result.append(item1) 516 } 517 } 518 return result 519 } 520 521 // Union returns the union of two []interface{} slices. 522 func Union(slice1, slice2 []interface{}) []interface{} { 523 return coreUnion(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), defaultEqualler).actual().([]interface{}) 524 } 525 526 // UnionWith returns the union of two []interface{} slices with Equaller. 527 func UnionWith(slice1, slice2 []interface{}, equaller Equaller) []interface{} { 528 return coreUnion(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), equaller).actual().([]interface{}) 529 } 530 531 // UnionG returns the union of two []T slices, is the generic function of Union. 532 func UnionG(slice1, slice2 interface{}) interface{} { 533 s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2) 534 return coreUnion(s1, s2, defaultEqualler).actual() 535 } 536 537 // UnionWithG returns the union of two []T slices with Equaller, is the generic function of UnionWith. 538 func UnionWithG(slice1, slice2 interface{}, equaller Equaller) interface{} { 539 s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2) 540 return coreUnion(s1, s2, equaller).actual() 541 } 542 543 // coreUnion is the implementation for Union, UnionWith, UnionG and UnionWithG. 544 func coreUnion(slice1, slice2 innerSlice, equaller Equaller) innerSlice { 545 result := makeSameTypeInnerSlice(slice1, 0, slice1.length()) 546 length1 := slice1.length() 547 for i1 := 0; i1 < length1; i1++ { 548 item1 := slice1.get(i1) 549 result.append(item1) 550 } 551 length2 := slice2.length() 552 for i2 := 0; i2 < length2; i2++ { 553 item2 := slice2.get(i2) 554 if !coreContains(slice1, item2, equaller) { 555 result.append(item2) 556 } 557 } 558 return result 559 } 560 561 // Intersect returns the intersection of two []interface{} slices. 562 func Intersect(slice1, slice2 []interface{}) []interface{} { 563 return coreIntersect(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), defaultEqualler).actual().([]interface{}) 564 } 565 566 // IntersectWith returns the intersection of two []interface{} slices with Equaller. 567 func IntersectWith(slice1, slice2 []interface{}, equaller Equaller) []interface{} { 568 return coreIntersect(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), equaller).actual().([]interface{}) 569 } 570 571 // IntersectG returns the intersection of two []T slices, is the generic function of Intersect. 572 func IntersectG(slice1, slice2 interface{}) interface{} { 573 s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2) 574 return coreIntersect(s1, s2, defaultEqualler).actual() 575 } 576 577 // IntersectWithG returns the intersection of two []T slices with Equaller, is the generic function of IntersectWith. 578 func IntersectWithG(slice1, slice2 interface{}, equaller Equaller) interface{} { 579 s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2) 580 return coreIntersect(s1, s2, equaller).actual() 581 } 582 583 // coreIntersect is the implementation for Intersect, IntersectWith, IntersectG and IntersectWithG. 584 func coreIntersect(slice1, slice2 innerSlice, equaller Equaller) innerSlice { 585 result := makeSameTypeInnerSlice(slice1, 0, 0) 586 length1 := slice1.length() 587 for i1 := 0; i1 < length1; i1++ { 588 item1 := slice1.get(i1) 589 if coreContains(slice2, item1, equaller) { 590 result.append(item1) 591 } 592 } 593 return result 594 } 595 596 // Deduplicate removes the duplicate items from []interface{} slice as a set. 597 func Deduplicate(slice []interface{}) []interface{} { 598 return coreDeduplicate(checkInterfaceSliceParam(slice), defaultEqualler).actual().([]interface{}) 599 } 600 601 // DeduplicateWith removes the duplicate items from []interface{} slice as a set with Equaller. 602 func DeduplicateWith(slice []interface{}, equaller Equaller) []interface{} { 603 return coreDeduplicate(checkInterfaceSliceParam(slice), equaller).actual().([]interface{}) 604 } 605 606 // DeduplicateG removes the duplicate items from []T slice as a set, is the generic function of Deduplicate. 607 func DeduplicateG(slice interface{}) interface{} { 608 return coreDeduplicate(checkSliceInterfaceParam(slice), defaultEqualler).actual() 609 } 610 611 // DeduplicateWithG removes the duplicate items from []T slice as a set with Equaller, is the generic function of DeduplicateWith. 612 func DeduplicateWithG(slice interface{}, equaller Equaller) interface{} { 613 return coreDeduplicate(checkSliceInterfaceParam(slice), equaller).actual() 614 } 615 616 // coreDeduplicate is the implementation for Deduplicate, DeduplicateWith, DeduplicateG and DeduplicateWithG. 617 func coreDeduplicate(slice innerSlice, equaller Equaller) innerSlice { 618 result := makeSameTypeInnerSlice(slice, 0, 0) 619 length := slice.length() 620 for idx := 0; idx < length; idx++ { 621 item := slice.get(idx) 622 if !coreContains(result, item, equaller) { // O(n^2) 623 result.append(item) 624 } 625 } 626 return result 627 } 628 629 // DeduplicateSelf removes the duplicate items from []interface{} slice as a set, by modifying given slice directly. 630 func DeduplicateSelf(slice []interface{}) []interface{} { 631 return coreDeduplicateSelf(checkInterfaceSliceParam(slice), defaultEqualler).actual().([]interface{}) 632 } 633 634 // DeduplicateSelfWith removes the duplicate items from []interface{} slice as a set with Equaller, by modifying given slice directly. 635 func DeduplicateSelfWith(slice []interface{}, equaller Equaller) []interface{} { 636 return coreDeduplicateSelf(checkInterfaceSliceParam(slice), equaller).actual().([]interface{}) 637 } 638 639 // DeduplicateSelfG removes the duplicate items from []T slice as a set, is the generic function of DeduplicateSelf, by modifying given slice directly. 640 func DeduplicateSelfG(slice interface{}) interface{} { 641 return coreDeduplicateSelf(checkSliceInterfaceParam(slice), defaultEqualler).actual() 642 } 643 644 // DeduplicateSelfWithG removes the duplicate items from []T slice as a set with Equaller, is the generic function of DeduplicateSelfWith, by modifying given slice directly. 645 func DeduplicateSelfWithG(slice interface{}, equaller Equaller) interface{} { 646 return coreDeduplicateSelf(checkSliceInterfaceParam(slice), equaller).actual() 647 } 648 649 // coreDeduplicate is the implementation for DeduplicateSelf, DeduplicateSelfWith, DeduplicateSelfG and DeduplicateSelfWithG. 650 func coreDeduplicateSelf(slice innerSlice, equaller Equaller) innerSlice { 651 length := slice.length() 652 if length <= 1 { 653 return slice 654 } 655 i := 1 656 for idx := 1; idx < length; idx++ { 657 item := slice.get(idx) 658 if !coreContains(slice.slice(0, i), item, equaller) { 659 slice.set(i, item) 660 i++ 661 } 662 } 663 return slice.slice(0, i) 664 } 665 666 // Compact removes the duplicate items in neighbor from []interface{} slice. 667 func Compact(slice []interface{}) []interface{} { 668 return coreCompact(checkInterfaceSliceParam(slice), defaultEqualler).actual().([]interface{}) 669 } 670 671 // CompactWith removes the duplicate items in neighbor from []interface{} slice with Equaller. 672 func CompactWith(slice []interface{}, equaller Equaller) []interface{} { 673 return coreCompact(checkInterfaceSliceParam(slice), equaller).actual().([]interface{}) 674 } 675 676 // CompactG removes the duplicate items in neighbor from []T slice, is the generic function of Compact. 677 func CompactG(slice interface{}) interface{} { 678 return coreCompact(checkSliceInterfaceParam(slice), defaultEqualler).actual() 679 } 680 681 // CompactWithG removes the duplicate items in neighbor from []T slice with Equaller, is the generic function of CompactWith. 682 func CompactWithG(slice interface{}, equaller Equaller) interface{} { 683 return coreCompact(checkSliceInterfaceParam(slice), equaller).actual() 684 } 685 686 // coreCompact is the implementation for Compact, CompactWith, CompactG and CompactWithG. 687 func coreCompact(slice innerSlice, equaller Equaller) innerSlice { 688 length := slice.length() 689 if length <= 1 { 690 return slice 691 } 692 result := makeSameTypeInnerSlice(slice, 1, 1) 693 last := slice.get(0) 694 result.set(0, last) 695 for idx := 1; idx < length; idx++ { // O(n) 696 item := slice.get(idx) 697 if !equaller(item, last) { 698 result.append(item) 699 last = item 700 } 701 } 702 return result 703 } 704 705 // CompactSelf removes the duplicate items in neighbor from []interface{} slice, by modifying given slice directly. 706 func CompactSelf(slice []interface{}) []interface{} { 707 return coreCompactSelf(checkInterfaceSliceParam(slice), defaultEqualler).actual().([]interface{}) 708 } 709 710 // CompactSelfWith removes the duplicate items in neighbor from []interface{} slice with Equaller, by modifying given slice directly. 711 func CompactSelfWith(slice []interface{}, equaller Equaller) []interface{} { 712 return coreCompactSelf(checkInterfaceSliceParam(slice), equaller).actual().([]interface{}) 713 } 714 715 // CompactSelfG removes the duplicate items in neighbor from []T slice, is the generic function of CompactSelf, by modifying given slice directly. 716 func CompactSelfG(slice interface{}) interface{} { 717 return coreCompactSelf(checkSliceInterfaceParam(slice), defaultEqualler).actual() 718 } 719 720 // CompactSelfWithG removes the duplicate items in neighbor from []T slice with Equaller, is the generic function of CompactSelfWith, by modifying given slice directly. 721 func CompactSelfWithG(slice interface{}, equaller Equaller) interface{} { 722 return coreCompactSelf(checkSliceInterfaceParam(slice), equaller).actual() 723 } 724 725 // coreCompactSelf is the implementation for CompactSelf, CompactSelfWith, CompactSelfG and CompactSelfWithG. 726 func coreCompactSelf(slice innerSlice, equaller Equaller) innerSlice { 727 length := slice.length() 728 if length <= 1 { 729 return slice 730 } 731 i := 1 732 last := slice.get(0) 733 for idx := 1; idx < length; idx++ { 734 item := slice.get(idx) 735 if !equaller(item, last) { 736 slice.set(i, item) 737 i++ 738 last = item 739 } 740 } 741 return slice.slice(0, i) 742 } 743 744 // Equal checks whether two []interface{} slices equal (the same length and all elements equal). 745 func Equal(slice1, slice2 []interface{}) bool { 746 return coreEqual(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), defaultEqualler) 747 } 748 749 // EqualWith checks whether two []interface{} slices equal (the same length and all elements equal) with Equaller. 750 func EqualWith(slice1, slice2 []interface{}, equaller Equaller) bool { 751 return coreEqual(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), equaller) 752 } 753 754 // EqualG checks whether two []T slices equal (the same length and all elements equal), is the generic function of Equal. 755 func EqualG(slice1, slice2 interface{}) bool { 756 s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2) 757 return coreEqual(s1, s2, defaultEqualler) 758 } 759 760 // EqualWithG checks whether two []T slices equal (the same length and all elements equal) with Equaller, is the generic function of EqualWith. 761 func EqualWithG(slice1, slice2 interface{}, equaller Equaller) bool { 762 s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2) 763 return coreEqual(s1, s2, equaller) 764 } 765 766 // coreEqual is the implementation for Equal, EqualWith, EqualG and EqualWithG. 767 func coreEqual(slice1, slice2 innerSlice, equaller Equaller) bool { 768 length1, length2 := slice1.length(), slice2.length() 769 if length1 != length2 { 770 return false 771 } 772 for idx := 0; idx < length1; idx++ { 773 item1, item2 := slice1.get(idx), slice2.get(idx) 774 if !equaller(item1, item2) { 775 return false 776 } 777 } 778 return true 779 } 780 781 // ElementMatch checks whether two []interface{} slices equal (ignore the order of the elements, but the number of duplicate elements should match). 782 func ElementMatch(slice1, slice2 []interface{}) bool { 783 return coreElementMatch(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), defaultEqualler) 784 } 785 786 // ElementMatchWith checks whether two []interface{} slices equal (ignore the order of the elements, but the number of duplicate elements should match) with Equaller. 787 func ElementMatchWith(slice1, slice2 []interface{}, equaller Equaller) bool { 788 return coreElementMatch(checkInterfaceSliceParam(slice1), checkInterfaceSliceParam(slice2), equaller) 789 } 790 791 // ElementMatchG checks whether two []T slices equal (ignore the order of the elements, but the number of duplicate elements should match), is the generic function of ElementMatch. 792 func ElementMatchG(slice1, slice2 interface{}) bool { 793 s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2) 794 return coreElementMatch(s1, s2, defaultEqualler) 795 } 796 797 // ElementMatchWithG checks whether two []T slices equal (ignore the order of the elements, but the number of duplicate elements should match) with Equaller, is the generic function of ElementMatchWith. 798 func ElementMatchWithG(slice1, slice2 interface{}, equaller Equaller) bool { 799 s1, s2 := checkTwoSliceInterfaceParam(slice1, slice2) 800 return coreElementMatch(s1, s2, equaller) 801 } 802 803 // coreElementMatch is the implementation for ElementMatch, ElementMatchWith, ElementMatchG and ElementMatchWithG. 804 func coreElementMatch(slice1, slice2 innerSlice, equaller Equaller) bool { 805 length1, length2 := slice1.length(), slice2.length() 806 visited := make([]bool, length2) 807 for idx1 := 0; idx1 < length1; idx1++ { 808 item1 := slice1.get(idx1) 809 exist := false 810 for idx2 := 0; idx2 < length2; idx2++ { 811 if visited[idx2] { 812 continue 813 } 814 item2 := slice2.get(idx2) 815 if equaller(item1, item2) { 816 visited[idx2] = true 817 exist = true 818 break 819 } 820 } 821 if !exist { 822 return false 823 } 824 } 825 826 for idx2 := 0; idx2 < length2; idx2++ { 827 if !visited[idx2] { 828 return false 829 } 830 } 831 832 return true 833 } 834 835 // Repeat generates a []interface{} with given value repeated given count. 836 func Repeat(value interface{}, count uint) []interface{} { 837 return coreRepeat(value, count, false).actual().([]interface{}) 838 } 839 840 // RepeatG generates a []T with given value repeated given count, is the generic function of Repeat. 841 func RepeatG(value interface{}, count uint) interface{} { 842 return coreRepeat(value, count, true).actual().(interface{}) 843 } 844 845 // coreRepeat is the implementation for Repeat and RepeatG. 846 func coreRepeat(value interface{}, count uint, g bool) innerSlice { 847 if value == nil { 848 g = false 849 } 850 slice := makeItemTypeInnerSlice(value, int(count), int(count), g) 851 for i := 0; i < int(count); i++ { 852 slice.set(i, value) 853 } 854 return slice 855 }