Reputation: 33944
Imagine that i have two arrays:
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0];
b = [5, 9, 6];
I want to find the indices of the values of b in a (only the first hit) ie:
c = [3, 6, 5];
Is there an easy Matlab native way to do this without looping and searching.
I have tried to use find() with:
find(a == b)
and it would work if you did this:
for i = 1:length(b)
index = find(a == b(i));
c = [c, index(1)]
end
But it would be ideal for it to be easier then this.
Upvotes: 28
Views: 88622
Reputation: 11168
You can compact your for loop easily with arrayfun into a simple one-liner:
arrayfun(@(x) find(a == x,1,'first'), b )
also see Scenia's answer for newer matlab versions (>R2012b).
Upvotes: 20
Reputation: 112759
Similar to @tmpearce's answer, but possibly faster:
[valid, result] = max(bsxfun(@eq, a(:), b(:).')); %'// max finds first occurrence
result = result(valid); %// this is necessary in case some value of b is not in a
Upvotes: 1
Reputation: 1629
This is actually built into ismember
. You just need to set the right flag, then it's a one liner and you don't need arrayfun. Versions newer than R2012b use this behavior by default.
Originally, ismember
would return the last occurence if there are several, the R2012a flag makes it return the first one.
Here's my testing results:
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0, 6];
b = [5, 9, 6];
[~,c] = ismember(b,a,'R2012a');
>> c
c =
3 6 5
Upvotes: 19
Reputation: 11
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0];
b = [5, 9, 6];
c = dsearchn(a',b');
Matlab requires a and b need to be column vectors, hence the transpose.
Upvotes: 1
Reputation: 124563
This is a fix to the ismember
approach that @Pursuit suggested. This way it handles multiple occurrences of one of the numbers, and returns the result in the correct order:
[tf,loc] = ismember(a,b);
tf = find(tf);
[~,idx] = unique(loc(tf), 'first');
c = tf(idx);
The result:
>> c
c =
3 6 5
Upvotes: 5
Reputation: 12345
Have you tried ismember
?
c_logical_mask = ismember(a, b);
or
c_indexes = find(ismember(a, b));
Upvotes: 1
Reputation: 12693
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0, 6];
b = [5, 9, 6];
[r c]=find(bsxfun(@eq,a,b')');
[~,ia,~]=unique(c,'first');
>> r(ia)
ans =
3
6
5
Note: I added an extra 6
at the end of a
to demonstrate finding only the first occurrence of each value.
Upvotes: 4