Asked by Alan
on 3 Dec 2011

Given two vectors A and B, find the index, idx into A of the element of B so that

A(idx)=B.

Now I know there must be many ways it can be done, but is there a one-liner?

For example if

A=[3 4 5 6 7];

B=[6 4 7];

then

[tf,loc]=ismember(A,B);

idx=[1:length(A)];

idx=idx(tf);

idx=idx(loc(tf));

disp(A(idx))

will do it but that is four steps. Is there a more elegant way?

Answer by Sven
on 3 Dec 2011

Edited by MathWorks Support Team
on 9 Nov 2018

Accepted Answer

There are a few options to get the indices you are looking for. The following output indices (idx) preserve the order in A of the shared values:

[sharedvals,idx] = intersect(A,B,’stable’)

You can also use the following command if the order in A is not necessary:

[tf,idx] = ismember(B,A)

Alan
on 3 Dec 2011

That's nice. Two lines is better than four. I hadn't thought of using the index of sort.

Alan
on 3 Dec 2011

I am wondering though if "intersect" and "sort" would be expensive on large arrays.

tc88
on 22 Aug 2016

meanwhile, the functionality of intersect has changed and a one-line solution is also possible using intersect:

[sharedVals,idxsIntoA] = intersect(B,A,'stable')

Be aware that the order of A and B must be changed, since the order of the first argument is retained.

Sign in to comment.

Answer by Alan
on 3 Dec 2011

Thanks for the three solutions. Here is a function to test all three. "method_1" wins as the most elegant and fastest, but the other two taught other useful ways of looking at the problem.

function test_solution

% set up the problem

N=1e6;

% A is a random vector of the integers to N

A=randperm(N);

% B is another vector of integers

B=[ 2 1 4 3 ];

% I'd like to find the indicies of the element of B in A

% such that A(idx)=B;

tic

idx=method_1(A,B);

toc

disp(A(idx));

tic

idx=method_2(A,B);

toc

disp(A(idx));

tic

idx=method_3(A,B);

toc

disp(A(idx));

function idx = method_1(A,B)

idx = arrayfun(@(x)find(A==x,1),B);

function idx = method_2(A,B)

[~,idx1] = intersect(A,B);

[~,idx2] = sort(B);

idx=idx1(idx2);

function idx = method_3(A,B)

[A,idx1] = sort(A);

[~,idx2] = histc(B,A);

idx = idx1(idx2);

Sven
on 4 Dec 2011

Iftikhar Ali
on 18 Oct 2015

Method 3 has solved my problem, thanks.

Sign in to comment.

Answer by Teja Muppirala
on 3 Dec 2011

If A is sorted, then I think this is probably the easiest (and also fastest?) way to do it.

[~,idx] = histc(B,A)

If A is not sorted, then:

[As,s_idx] = sort(A);

[~,tmp] = histc(B,As);

idx = s_idx(tmp)

Sign in to comment.

Answer by Stephen Politzer-Ahles
on 8 Jul 2014

Edited by Stephen Politzer-Ahles
on 8 Jul 2014

The following should also work for your situation, and just needs one line:

A=[3 4 5 6 7];

B=[6 4 7];

idx = arrayfun( @(x)( find(A==x) ), B );

Sign in to comment.

Answer by Junhong YE
on 21 Jul 2014

I think find(ismember(A,B)) would do it.

Sign in to comment.

Answer by Iftikhar Ali
on 18 Oct 2015

I am facing an issue finding indices of element matching in two arrays.

xpts = [0 0.0004 0.0011 0.0018 0.0025 0.003]; x = 0:0.0001:0.003; index1 = find(ismember(x, xpts));

It returns index1 = [1 5 12 26 31]

but there is one more element '0.0018' in x which also belongs xpts, and not including in the answer.

Similarly when I increase the number of points in x, there are few elements that are missed or not recognized by the find command. What's going wrong here.

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 3 Comments

## Alan (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/22926-finding-the-indices-of-the-elements-of-one-array-in-another#comment_49943

## Philip (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/22926-finding-the-indices-of-the-elements-of-one-array-in-another#comment_239476

## Leandro Coelho (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/22926-finding-the-indices-of-the-elements-of-one-array-in-another#comment_376433

Sign in to comment.