Finding the indices of the elements of one array in another

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?

댓글 수: 3

Actually, my solution doesn't work in general. Sometimes but not always.
MATLAB supports logical indexing. No need to use "find":
A = A( ismember( A, B ) );
Another option: intersect(A,B)

댓글을 달려면 로그인하십시오.

 채택된 답변

Sven
Sven 2011년 12월 3일
편집: MathWorks Support Team 2018년 11월 9일
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)

댓글 수: 3

That's nice. Two lines is better than four. I hadn't thought of using the index of sort.
I am wondering though if "intersect" and "sort" would be expensive on large arrays.
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.

댓글을 달려면 로그인하십시오.

추가 답변 (6개)

Alan
Alan 2011년 12월 3일
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);

댓글 수: 3

Alan, well done in asking a question clearly (with code), and in particular taking the time to give feedback on the results above
Method 3 has solved my problem, thanks.
Method one also works if there are multiple occurences of B in A. Intersect fails in this case.

댓글을 달려면 로그인하십시오.

Alan
Alan 2011년 12월 6일
Thinking again, I realize that ismember is all I need
[~,idx]=ismember(B,A)
will do it.

댓글 수: 2

This is by far the best answer!
obviously this will fail to get A(idx), if any elements of idx are 0 (i.e. B not in A) and robust usage should be clarified to A(idx(idx ~= 0)).

댓글을 달려면 로그인하십시오.

Iftikhar Ali
Iftikhar Ali 2015년 10월 18일

1 개 추천

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.
Teja Muppirala
Teja Muppirala 2011년 12월 3일
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)
Stephen Politzer-Ahles
Stephen Politzer-Ahles 2014년 7월 8일
편집: Stephen Politzer-Ahles 2014년 7월 8일
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 );
Junhong YE
Junhong YE 2014년 7월 21일

0 개 추천

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

카테고리

도움말 센터File Exchange에서 Logical에 대해 자세히 알아보기

질문:

2011년 12월 3일

댓글:

2020년 1월 18일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by