views:

232

answers:

2

I have this cell array in MATLAB:

y = { 'd' 'f' 'a' 'g' 'g' 'a' 'w' 'h'}

I use unique(y) to get rid of the duplicates but it rearranges the strings in alphabetical order:

>> unique(y)

ans =

'a'    'd'    'f'    'g'    'h'    'w'

I want to remove the duplicates but keep the same order. I know I could write a function do do this but was wondering if there was a simpler way using unique to remove duplicates while keeping the same order just with the duplicates removed.

I want it to return this:

>> unique(y)

ans = 

'd'    'f'    'a'    'g'    'w'    'h'
+3  A: 

If you look at the documentation for unique, there's the option to return an index along with the sorted array. You can specify whether you want the first or last occurrence of a number to be returned to the index as well.

For example:

a=[5, 3, 4, 2, 1, 5, 4];

[b,order]=unique(a,'first')

returns

b=[1, 2, 3, 4, 5] and m=[5, 4, 2, 3, 1]

You can sort your order array and store the index next

[~,index]=sort(order) %# use a throw-away variable instead of ~ for older versions

and finally re-index b

b=b(index)
Doresoom
+1: Looks like we revised our answers at the same time.
gnovice
+8  A: 

Here's one solution that uses some additional input and output arguments that UNIQUE has:

>> y = { 'd' 'f' 'a' 'g' 'g' 'a' 'w' 'h'};  %# Sample data
>> [junk,index] = unique(y,'first');        %# Capture the index, ignore junk
>> y(sort(index))                           %# Index y with the sorted index

ans = 

    'd'    'f'    'a'    'g'    'w'    'h'
gnovice
Now why didn't I think of doing it this way? +1
Doresoom
+1: I already have a function in my path called `uniq.m` that does this exactly, I use it all the time :)
Amro