# general code for sorting inside cell

1 view (last 30 days)
NA on 7 Mar 2019
Commented: NA on 9 Mar 2019
ref=69;
A={[1,2,3,12],[19,34,37,15,33,35,36],[19,20,21,22,23,5,8,11,13,15,17],[37,38,65,40,42,49,66],[5,11,3,12],[69,19,21,22,23],[69,70,75]};
amount=[];
ref_include_index = cellfun(@(v)any(ismember(v,ref)),A);
ref_include_array = A(ref_include_index); % find array that include ref
amount=[ref_include_array{:},amount];
amount=unique(amount);
idv = cellfun(@(v)any(ismember(v,amount)),A);
idvv=A(idv&~ref_include_index);
amount=[idvv{:},amount];
amount=unique(amount);
idr = cellfun(@(v)any(ismember(v,amount)),A);
idrr=A(idr&~idv&~ref_include_index);
amount=[idrr{:},amount];
amount=unique(amount);
idm = cellfun(@(v)any(ismember(v,amount)),A);
idmm=A(idm&~idr&~idv&~ref_include_index);
amount=[idmm{:},amount];
amount=unique(amount);
result=[ref_include_array,idvv,idrr,idmm];
this code sorting A according to ref. if size of A is changing I have to copy and paste this line
idm = cellfun(@(v)any(ismember(v,amount)),A);
idmm=A(idm&~idr&~idv&~ref_include_index);
amount=[idmm{:},amount];
amount=unique(amount);
Is there any way to write better code for this?

Jan on 7 Mar 2019
You forgot to explain, what the code should do. "If size of A is changing" can mean, that A becomes empty or a {1000 x 200} cell array. So why do you have to add these 4 lines in this case?
I ran your code, but the purpose is not getting clear to me.
NA on 7 Mar 2019
I want to change order of cell A according to this:
As ref is 69, find all array that has 69 inside. ref_include_array=[69,19,21,22,23],[69,70,75]
find all array that have 19,21,22,23 and 70,75 inside (all element of ref_include_array except first element in array). idvv=[19,34,37,15,33,35,36],[19,20,21,22,23,5,8,11,13,15,17]
next step,find all array that have 34,37,15,33,35,36 and 20,21,22,23,5,8,11,13,15,17inside. idrr=[37,38,65,40,42,49,66],[5,11,3,12]
find all array that have 38,65,40,42,49,66 and 11,3,12. idmm=[1,2,3,12]
As in this example I do not have other array that contain 1,2,3 code should stop.
so the New_A order become. New_A={[69,19,21,22,23],[69,70,75], [19,34,37,15,33,35,36],[19,20,21,22,23,5,8,11,13,15,17],[37,38,65,40,42,49,66],[5,11,3,12],[1,2,3,12]}
"If size of A is changing" can mean, that A becomes empty or a {1000 x 200} cell array.
I mean length of A is changing.now, A is 1*7 cell, A become 1*90.
A does not become empty or a {1000 x 200} cell array.

Jan on 7 Mar 2019
Edited: Jan on 7 Mar 2019
ref = 69;
A = {[1,2,3,12],[19,34,37,15,33,35,36],[19,20,21,22,23,5,8,11,13,15,17], ...
[37,38,65,40,42,49,66],[5,11,3,12],[69,19,21,22,23],[69,70,75]};
Result = {};
while ~isempty(A) % As long as A is not empty:
% Find vectors, which contain any element of ref:
match = cellfun(@(a) any(ismember(a, ref)), A);
% Attach found vectors to the output:
Result = cat(2, Result, A(match));
% Find new reference vector:
ref = unique(cat(2, A{match}));
% Crop matched vectors from A:
A = A(~match);
end

NA on 8 Mar 2019
Thank you. I also want to sort inside each array according to index_base.
for [5,11,3,12] index_base is 4, means that element 12 is a base. So,I want to move it to the first element inside this array. [12,5,11,3]
or [41,69] index_base is 2, means that element 69 is a base. So,I want to move it to first element inside this array. [69,41]
[37,38,65,40,42,49,66] index_base is 4, should change to [40,37,38,65,42,49,66].
for this reason I add this code in your code, but I have a problem to fix it.
ref = 69;
A = {[1,2,3,12],[19,34,37,15,33,35,36],[19,20,21,22,23,5,8,11,13,15,17], ...
[37,38,65,40,42,49,66],[5,11,3,12],[69,19,21,22,23],[69,70,75],[17,31,32,113],[41,69]};
index_base={[1],[1],[1],[4],[4],[1],[1],[2],[2]};
Result = {};
while ~isempty(A) % As long as A is not empty:
% Find vectors, which contain any element of ref:
match = cellfun(@(a) any(ismember(a, ref)), A);
% Attach found vectors to the output:
Result = cat(2, Result, A(match));
% want to sort according to index_base:
fun = @(v) sort(0-(v==ref));
[~,ids] = cellfun(fun,Result,'uni',0);
Result = cellfun(@(v,x)v(x),Result,ids,'uni',0);
% Find new reference vector:
ref = unique(cat(2, A{match}));
% Crop matched vectors from A:
A = A(~match);
end
result should be
Result={[69,19,21,22,23],[69,70,75],[69,41],[19,34,37,15,33,35,36],[19,20,21,22,23,5,8,11,13,15,17],...
[40,37,38,65,42,49,66],[12,5,11,3],[31,17,32,113],[1,2,3,12]}
Jan on 8 Mar 2019
Why not "sorting" the arrays before the processing?
A = {[1,2,3,12],[19,34,37,15,33,35,36],[19,20,21,22,23,5,8,11,13,15,17], ...
[37,38,65,40,42,49,66],[5,11,3,12],[69,19,21,22,23],[69,70,75],[17,31,32,113],[41,69]};
index_base={[1],[1],[1],[4],[4],[1],[1],[2],[2]};
for iA = 1:numel(A)
if index_base{iA} ~= 1
v = A{iA};
m = (1:numel(v)) == index_base{iA};
A{iA} = [v(m), v(~m)];
end
end
NA on 9 Mar 2019
Thanks