14
\$\begingroup\$

In the shortest amount of code in any programming language, filter out the duplicate items in an array of which the order is irrelevant.

Here are some test cases:

[1, 2, 2, 3, 1, 2, 4] => [1, 2, 3, 4]
['a', 'a', 'b', 'a', 'c', 'a', 'd'] => ['a', 'b', 'c', 'd']

I also should note that there currently aren't any open questions that meet these exact criteria.

\$\endgroup\$
3
  • 3
    \$\begingroup\$ Related (char input, no built-in allowed) \$\endgroup\$
    – Luis Mendo
    Mar 21, 2020 at 13:06
  • 2
    \$\begingroup\$ Preserving order of first (or last) appearance would be a different challenge that's perhaps more interesting (because Set builtins and sorting with duplicate merging won't work). It might be good if one of the test-cases showed that you're definitely allowed to re-order the elements you do keep, like [1, 2] => [2, 1] being valid. I'd also suggest tweaking the title to something that doesn't imply order preservation. Perhaps involving the phrase "set of unique items" \$\endgroup\$ Mar 23, 2020 at 10:22
  • \$\begingroup\$ Can answers assume that the list does not contain empty strings? \$\endgroup\$ Mar 29, 2020 at 21:36

26 Answers 26

15
\$\begingroup\$

1-byte built-ins

05AB1E (legacy)

Ù

Try it online!

Alternatively:

ê

Try it online!

APL (Dyalog Unicode)

Try it online!

Jelly

Q

Try it online!

W

U

Stax

u

MATL

u

Try it online!

MathGolf

Try it online!

Seriously/Actually

Japt

â

Try it online!

Pyth

{

Try it online!

Husk

u

Try it online!

Pyke

}

Try it online!

Canvas

Try it online!

Vyxal

U

Try it Online!

\$\endgroup\$
4
  • 2
    \$\begingroup\$ And once again, the most boring answer gets voted to the top. But at least you took the time to compile a collection. \$\endgroup\$
    – wastl
    Mar 22, 2020 at 0:59
  • 5
    \$\begingroup\$ @wastl Boring answers getting voted to the top is another story, but at least we have a consensus about using a community answer to group all trivial solutions. \$\endgroup\$
    – Arnauld
    Mar 22, 2020 at 11:37
  • \$\begingroup\$ Ah, I can't see that it's a community wiki in the app, it just says "Edited by Arnauld" \$\endgroup\$
    – wastl
    Mar 22, 2020 at 11:52
  • \$\begingroup\$ It always bothered me that this is called unique elements. Shouldn't it be distinct? To me, the unique elements in 1, 2, 2, 3, 1, 2, 4 are 3,4 since they appear exactly once. \$\endgroup\$
    – mappo
    Apr 9, 2020 at 21:30
6
\$\begingroup\$

Python 3, 15 3 bytes

Reduced to 3 bytes thanks to a'_'!!!

set

Try it online!

Without set

Python 3, 35 \$\cdots\$30 29 bytes

Saved 3 bytes thanks to a'_'!!!
Saved a byte thanks to Jitse!!!
Saved a byte thanks to Jonathan Allan!!!

lambda l:list(dict(zip(l,l)))

Try it online!

\$\endgroup\$
9
  • \$\begingroup\$ Or just... 3 bytes \$\endgroup\$
    – user92069
    Mar 21, 2020 at 11:00
  • \$\begingroup\$ @a'_' Brilliant - thanks! :-) \$\endgroup\$
    – Noodle9
    Mar 21, 2020 at 11:05
  • \$\begingroup\$ Very nice way of using set +1 \$\endgroup\$
    – ElPedro
    Mar 21, 2020 at 11:50
  • \$\begingroup\$ Anyway, 31 bytes without set. \$\endgroup\$
    – user92069
    Mar 21, 2020 at 12:06
  • \$\begingroup\$ @a'_' Sweet - thanks! :-) \$\endgroup\$
    – Noodle9
    Mar 21, 2020 at 12:16
4
\$\begingroup\$

Python 3, 3 bytes

set

Try it online! It also works on Python 2

Or without set:

Python 3, 34 29 26 bytes

lambda l:[*dict(zip(l,l))]

Try it online! Thanks to Jonathan Alan and Surculose Sputum for helping me golf this one!

\$\endgroup\$
2
  • \$\begingroup\$ ...that non-set answer can be lambda l:list({e:1for e in l}) saving four \$\endgroup\$ Mar 21, 2020 at 18:34
  • \$\begingroup\$ The non-set answer can be lambda l:[*dict(zip(l,l))], making use of splat operator to save 3 bytes \$\endgroup\$ Mar 21, 2020 at 19:01
4
\$\begingroup\$

Java 8, 27 15 bytes

S->S.distinct()

Stream I/O.

Try it online.

27 22 bytes:

java.util.HashSet::new

-5 bytes thanks to @OlivierGrégoire.

List input, Set output.

Try it online.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ java.util.HashSet::new for the List input, Set output. \$\endgroup\$ Mar 23, 2020 at 11:04
  • 1
    \$\begingroup\$ @OlivierGrégoire Ah, of course. I always forget about ::.. Thanks! \$\endgroup\$ Mar 23, 2020 at 11:08
4
\$\begingroup\$

Ruby, 8 bytes

->a{a&a}

or

->a{a|a}

Try it online!

Set intersection (&) or set union (|), both of which remove duplicates. Shorter than the built-in uniq method.

\$\endgroup\$
3
\$\begingroup\$

Retina 0.8.2, 6 bytes

D`
G`.

Try it online! Doesn't work on empty strings. Explanation:

D`

Replace all duplicates with empty strings.

G`.

Remove all empty strings.

\$\endgroup\$
2
  • \$\begingroup\$ Where do the rules state that your program is allowed to assume the input does not contain empty strings? \$\endgroup\$ Mar 22, 2020 at 17:32
  • \$\begingroup\$ I'm not claiming it does, but as yet none of the test cases include empty strings. \$\endgroup\$
    – Neil
    Mar 22, 2020 at 17:49
3
\$\begingroup\$

JavaScript (Node.js), 13 bytes

a=>new Set(a)

Try it online!

Unfortunately Set must be used with new, otherwise the answer will be just 3 bytes: Set, as a function.

\$\endgroup\$
6
  • \$\begingroup\$ But you are returning a set, instead of an array. \$\endgroup\$
    – kanine
    Mar 21, 2020 at 18:13
  • \$\begingroup\$ @kanine the specification does not state we must return an array, it only specifies we'll be given one and must filter out duplicates. \$\endgroup\$ Mar 21, 2020 at 18:25
  • \$\begingroup\$ @kanine Even so changing the set into an array costs only 5 bytes. \$\endgroup\$ Mar 22, 2020 at 4:51
  • \$\begingroup\$ @JonathanAllan, but looking as the test cases, it demands for an array. \$\endgroup\$
    – kanine
    Mar 22, 2020 at 6:33
  • \$\begingroup\$ @kanine we do not define challenges by their test cases. We also prefer loose I/O rules on this site. Note that the OP has also specified the input as "an array of which the order is irrelevant" which I would imagine means I/O is less restrictive than a list to the point of just meaning "container". If you think there is a point of contention here you should just ask OP to clarify in a comment under the question. \$\endgroup\$ Mar 22, 2020 at 13:15
3
\$\begingroup\$

Batch, 182 Bytes

@Echo Off&Setlocal EnableDelayedExpansion
For %%A In (%~1)do (
Set M=F
IF "!O!"=="" (Set O=%%A) Else (
For %%B in (!O!)do If %%A==%%B Set M=T
IF !M!==F Set O=!O!,%%A))
ECHO(!O!

TIO not available.

Builds a string starting with first element of the original string, compares each element of the new string against the next element of the original string, assigning and testing a troothy value before appending the next element to the new string.

\$\endgroup\$
2
\$\begingroup\$

Wolfram Language (Mathematica), 5 bytes

Union

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Io, 18 bytes

Io doesn't allow assigning functions. It's terrible!

method(x,x unique)

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Charcoal, 9 bytes

W⁻θυ⊞υ⊟ιυ

Try it online! Link is to verbose version of code. Works best on strings due to the way Charcoal prints numbers by default. Explanation:

W⁻θυ

Remove all occurrences of elements in the result from the input. While this temporary value is not empty...

⊞υ⊟ι

... push the last element of that value to the result.

υ

Print the result.

\$\endgroup\$
2
\$\begingroup\$

Haskell, 29 bytes

f(a:b)=a:f[x|x<-b,x/=a]
f x=x

Try it online!

This answer gives us the list with the first occurrence of every element.

Haskell, 33 bytes

f(a:b)=[a|notElem a b]++f b
f x=x

Try it online!

This answer gives us the last occurrence of every element.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Does not import Data.List;nub do the same at 20 bytes? \$\endgroup\$ Mar 21, 2020 at 14:03
  • \$\begingroup\$ @JonathanFrech Probably \$\endgroup\$
    – Wheat Wizard
    Mar 21, 2020 at 14:12
2
\$\begingroup\$

Erlang (escript), 41 bytes

Great thanks for the Haskell answer! (so that I can port it)

u([H|T])->[H]++u([X||X<-T,X/=H]);u(I)->I.

Try it online!

Erlang (escript), 79 72 bytes

It's a recursive definition of uniquifying. The premise is that Erlang doesn't have a set-conversion built-in.

u([H|T])->case string:find(T,[H])of nomatch->[H];_->[]end++u(T);u(I)->I.

Try it online!

Explanation

u([H|T])-> % Try to split the input into a head & tail.

case string:find(T,[H])of
           % Check whether H is a substring of T.
           % Strings are lists in Erlang, so it
           % doesn't raise a type error when applied on lists.

nomatch->[H];
           % If false, return head.
_->[]end   % Else, return empty list.
++u(T);    % Recurse down until ...

u(I)       % ... the operand is an empty list,
->I.       % where the operand is returned
```
\$\endgroup\$
2
\$\begingroup\$

Sledgehammer, 2 bytes

⠓⣻

Decompresses into this Wolfram Language function:

Union
\$\endgroup\$
1
  • \$\begingroup\$ Surprised that Sledgehammer doesn't have a 1-byte built-in... \$\endgroup\$
    – user92069
    Mar 22, 2020 at 1:51
2
\$\begingroup\$

perl -E, 23 bytes

@_{<>}=0;say for keys%_

Reads an array from STDIN, one element per line. Writes the unique elements to STDOUT, elements separated by two newlines.

(No TIO link, as it seems to not terminate the final line of the input with a newline, which leads to an incorrect output).

\$\endgroup\$
1
  • \$\begingroup\$ You can manually add an empty line at the end of input. \$\endgroup\$
    – wastl
    Mar 22, 2020 at 1:12
2
\$\begingroup\$

R, 6 bytes

unique

Try it online!

\$\endgroup\$
2
\$\begingroup\$

perl -MList::Util=uniq -E, 17 bytes

say for uniq@ARGV

Accepts an array as arguments, prints the unique elements to STDOUT, one element per line. TIO

\$\endgroup\$
1
  • \$\begingroup\$ If you take the input on STDIN, you can save 3 bytes: Try it online! \$\endgroup\$
    – Xcali
    Mar 23, 2020 at 15:07
1
\$\begingroup\$

IBM/Lotus Notes Formula, 10 bytes

@Unique(i)

Takes input from multi-value field i. Screenshots below.

enter image description here

enter image description here

\$\endgroup\$
1
\$\begingroup\$

Symja, 16 bytes

DeleteDuplicates

Try It Online!

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Can't you just go with DeleteDuplicates? \$\endgroup\$
    – RGS
    Mar 21, 2020 at 22:52
  • \$\begingroup\$ @RGS I'm not sure about function rules with Symja. I'll probably ask a meta question about what I can and can't include. \$\endgroup\$
    – lyxal
    Mar 21, 2020 at 22:53
  • \$\begingroup\$ I'm pretty sure you can \$\endgroup\$
    – RGS
    Mar 21, 2020 at 22:55
  • \$\begingroup\$ @RGS I was more saying I don't know if I can say DeleteDuplicates without the function declaration m:=. \$\endgroup\$
    – lyxal
    Mar 21, 2020 at 22:58
  • 1
    \$\begingroup\$ @RGS I see what you mean. Thanks! \$\endgroup\$
    – lyxal
    Mar 21, 2020 at 23:04
1
\$\begingroup\$

Clojure, 3 bytes

set

Try it online!

Returns a set, or preserving order:

Clojure, 8 bytes

distinct

Try it online!

\$\endgroup\$
1
\$\begingroup\$

MOO, 36 bytes

return #372:remove_duplicates(@args)

Extremely implementation-specific. The shortest non-implementation-specific way of doing this is return $list_utils:remove_duplicates(@args) (43 bytes).

Unfortunately, functions aren't first-class objects in this language, so #372:remove_duplicates (22 bytes) is a syntax error and thus isn't valid.

The shortest way of doing this without using a builtin is x={};for y in (args[1])x=setadd(x,y);endfor return x; (53 bytes)

\$\endgroup\$
1
\$\begingroup\$

T-SQL, 24 bytes

SELECT DISTINCT v FROM t

Takes input as separate rows in a table t with varchar field v, which is permitted per our IO rules.

Without an ORDER BY, SQL returns the rows in a non-prescribed order.

\$\endgroup\$
1
\$\begingroup\$

C++ (gcc), 69 bytes

#import<set>
using s=std::set<int>;s f(int*a,int l){return s{a,a+l};}

This is what I like about C++: It has a lot of features.

Try it online!

\$\endgroup\$
1
\$\begingroup\$

C (gcc), 86 bytes

i,j;f(a,l)int*a;{for(i=l;i--;)for(j=l;j--;)i-j?a[i]-a[j]?:bcopy(a-~i,a+i,--l-i<<2):0;}

Hoping to roll the two loops together.

Try it online!

C (gcc), 87 bytes

i,j;f(a,l)int*a;{for(i=j=l;i-=j--==l;j=j?:l)i-j?a[i]-a[j]?:bcopy(a-~i,a+i,--l-i<<2):0;}

Turns out longer.

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ I think you should return the resulting length, like this 82-byter. Otherwise we never know where the resulting array ends. \$\endgroup\$
    – Bubbler
    Mar 31, 2020 at 6:17
1
\$\begingroup\$

sh + POSIX utilities, 7 bytes

sort -u

sh + POSIX utilities, 9 bytes

sort|uniq

Notes

  • The TIO uses bash because it doesn't provide plain sh, but it should work fine in any shell.
  • I was flexible with the input (one entry of the array per line, no other markers) because sh doesn't have arrays. If you wanted to do it with, e.g., bash arrays, you could do this (TIO):
a=(1 2 2 3 1 2 4 a a b a c a d)
printf '%s\n' "${a[@]}" | sort -u
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Hey there, welcome! You may want to add a TIO link to your submission so that others can try it out, if possible. Also, in the first option, why don't you go with just uniq? \$\endgroup\$
    – RGS
    Mar 23, 2020 at 17:33
  • 2
    \$\begingroup\$ @RGS if uniq’s input isn’t sorted, it will only remove consecutive dupes. I was posting from mobile so no link :) \$\endgroup\$ Mar 23, 2020 at 18:34
  • \$\begingroup\$ gnu.org/software/coreutils/manual/html_node/… Based on GNU uniq documentation, you could use uniq -d, but I'm not sure if that's available in POSIX uniq. \$\endgroup\$
    – George
    Mar 23, 2020 at 19:09
0
\$\begingroup\$

Factor, 7 bytes

members

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.