Find duplicates in sequences of strings

See Robby Pelssers Blog
In this version the data is a sequence of strings rather than integers.

Setup test data

The test data is regenerated for each script so the outputs are not the same.

XQuery

let $n := 1000
let $max := 500
return 
   for $i in (1 to $max)  return xs:string(xs:integer(util:random() * $n))

Result

841 785 21 723 43 424 966 258 255 380 959 597 593 376 587 708 597 136 223 969 278 671 447 201 820 384 121 33 845 632 150 642 15 992 334 81 859 336 425 547 36 10 592 950 742 35 30 853 898 313 820 379 373 286 237 710 748 762 248 969 741 331 671 606 925 103 238 600 921 113 56 870 838 729 315 471 95 297 380 388 970 449 220 408 939 784 124 463 890 651 839 29 971 516 973 138 501 188 875 665 503 709 200 907 385 598 474 510 94 455 498 618 653 32 624 630 470 144 882 984 858 341 863 269 471 576 769 375 290 380 983 237 840 74 198 902 407 331 822 0 835 957 122 325 599 139 500 132 577 339 350 197 308 984 41 271 932 741 459 679 887 328 919 340 640 277 481 961 85 447 365 543 434 122 263 894 245 875 787 675 628 242 640 258 763 722 26 343 255 738 783 878 741 662 13 357 234 521 486 419 140 607 33 709 404 603 763 227 31 76 433 500 414 469 69 971 882 127 221 173 303 467 655 370 966 403 568 886 563 114 197 93 690 214 612 983 776 375 550 639 305 206 732 633 576 706 360 639 729 752 715 86 856 300 665 578 584 844 64 456 127 837 446 872 676 669 925 954 664 357 765 821 395 430 139 736 994 207 465 159 809 55 937 241 739 861 220 12 477 74 688 673 568 145 605 594 4 720 551 788 866 982 830 100 658 37 804 818 166 25 63 853 455 861 322 882 670 993 83 493 695 87 286 326 872 465 916 151 526 416 108 26 333 7 433 735 527 103 870 10 372 911 764 766 251 388 34 331 828 402 305 465 709 514 950 295 767 294 179 847 923 362 338 882 70 537 677 685 895 370 971 622 473 445 357 224 629 430 976 793 57 252 175 280 377 512 255 729 875 331 286 586 162 813 204 838 350 776 963 951 221 339 734 760 999 191 422 245 969 579 957 279 106 240 202 738 540 597 403 616 91 93 854 70 349 15 571 106 695 40 701 12 541 107 870 871 396 123 294 520 10 901 749 840 751 749 119 644 942 792 891 374 615 270 949 122 411 910 43 285 665 95 560 902 313 211 687 289 847 671 296 937 248 129 441 901 896 68 449 62 319 865 885 994 394 478 904 850 738 325 319 788 674 161 367 669 435 111 480 800

Distinct Values

XQuery

let $values := $context
let $distinctvalues := distinct-values($values)
let $duplicates := 
    for $value in $distinctvalues 
    return if (count(index-of($values, $value)) > 1) then $value else ()
return  $duplicates

Result

656 305 200 567 825 262 636 60 292 625 644 413 922 899 500 898 995 535 836 772 807 273 474 881 214 573 402 51 124 368 304 449 724 665 4 977 20 610 861 609 67 612 216 115 965 375 114 506 289 597 501 704 775 979 630 910 35 359 183 21 661 877 499 195 47 961 466 516 678 288 362 300 171 942 212 191 691 638 321 575 622 468 447 372 933 179 568 541 523 589 205 72 694

Distinct Values2

as suggested by Michael Westbay

XQuery

let $values := $context
let $distinctvalues := distinct-values($values)
let $duplicates := 
   for $value in distinct-values($values)
   return if (count($values[.=$value]) gt 1) then $value else ()
return $duplicates

Result

241 37 680 618 767 326 995 99 438 754 27 61 807 609 141 442 651 474 314 772 800 769 265 676 381 334 677 721 726 401 881 937 518 56 780 924 776 253 180 757 961 190 424 891 840 885 505 354 553 229 971 982 679 491 636 683 798 875 200 386 510 84 910 82 935 969 701 364 686 599 717 980 546 519 79 658 736 991 149 468 843 826 22 270 972 835 393

index-of()

XQuery

let $values := $context
let $duplicates := $values[index-of($values, .)[2]]
return  $duplicates

Result

255 405 58 279 950 554 825 776 449 264 52 95 184 143 989 899 861 980 757 315 683 574 796 159 3 75 108 920 56 624 8 47 341 455 701 145 88 11 868 625 571 227 77 903 430 827 597 789 415 365 999 372 853 285 619 94 709 384 935 392 335 303 720 499 812 809 951 31 908 552 260 41 383 297 30 508 612 42 909 169 787 539

count

XQuery

let $values := $context
let $duplicates :=
   distinct-values(
      for $value in $values
      return 
           if (count($values[. eq $value]) > 1)
           then $value
           else ()
     ) 
return $duplicates

Result

956 765 971 92 505 411 600 203 894 295 75 461 359 889 163 431 691 920 713 492 655 49 922 880 815 466 695 566 183 650 499 405 283 381 961 254 977 105 738 522 137 302 877 343 550 313 740 340 2 909 164 941 793 502 34 223 914 705 507 221 544 653 571 355 290 300 701 301 573 974 728 166 436 402 774 565 749 758 178 488 836 578 182 551 339 825 983 943 947 344 831 548 779 980 494 247 518 323

group

as suggested by Wolfgang - requires XQuery 3.0.

XQuery

let $values := $context
let $duplicates :=
    for $value in $values
    group by $key := $value
    return $value[2] 
return $duplicates

Result

74 223 808 558 316 46 433 183 409 276 522 369 248 365 458 878 148 991 846 88 237 596 84 818 814 564 899 810 286 496 504 714 4 928 557 795 803 432 646 949 336 703 453 941 211 635 514 264 990 591 414 902 108 7 76 802 552 645 488 734 363 335 299 545 388 876 513 118 114 840 937 816 562 776 744 228 103 317 338 705 213 786 306 544 879 32 593 722 819 960 198 682 658 287 892 134 501