4

I have a vector in Matlab B of dimension nx1 that contains the integers from 1 to n in a certain order, e.g. n=6 B=(2;4;5;1;6;3).

I have a vector A of dimension mx1 with m>1 that contains the same integers in ascending order each one repeated an arbitrary number of times, e.g. m=13 A=(1;1;1;2;3;3;3;4;5;5;5;5;6).

I want to get C of dimension mx1 in which the integers in A are reordered following the order in B. In the example, C=(2;4;5;5;5;5;1;1;1;6;3;3;3)

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
TEX
  • 2,249
  • 20
  • 43

4 Answers4

5

One approach with ismember and sort -

[~,idx] = ismember(A,B)
[~,sorted_idx] = sort(idx)
C = B(idx(sorted_idx))

If you are into one-liners, then another with bsxfun -

C = B(nonzeros(bsxfun(@times,bsxfun(@eq,A,B.'),1:numel(B))))
Divakar
  • 218,885
  • 19
  • 262
  • 358
3

This requires just one sort and indexing:

ind = 1:numel(B);
ind(B) = ind;
C = B(sort(ind(A)));
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
2

Another approach using repelem, accumarray, unique

B=[2;4;5;1;6;3];
A=[1;1;1;2;3;3;3;4;5;5;5;5;6];

counts = accumarray(A,A)./unique(A);
repelem(B,counts(B));

%// or as suggested by Divakar 
%// counts = accumarray(A,1);
%// repelem(B,counts(B));

PS: repelem was introduced in R2015a. If you are using a prior version, refer here

Community
  • 1
  • 1
Santhan Salai
  • 3,888
  • 19
  • 29
0

Another solution using hist, but with a loop and expanding memory :(

y = hist(A, max(A))
reps = y(B);
C = [];
for nn = 1:numel(reps)
    C = [C; repmat(B(nn), reps(nn), 1)];
end
learnvst
  • 15,455
  • 16
  • 74
  • 121