Question

I have in Matlab a cell named: elem

 [36 29]
 []
 [30 29]
 [30 18]
 []
 [31 29]
 []
 []
 [8 9]
 [32 30]

and a matrix named: conn

1   2
1   3
1   4
1   5
2   3
2   4
2   5
3   4
3   5
4   5

and i want to make 2 new matrices which will contain only the elements that correspond to non-empty cells of elem without using a for loop. For example the correct result would be:

29  36
29  30
18  30
29  31
8   9
30  32

and:

1   2
1   4
1   5
2   4
3   5
4   5

Any help would be greatly appreciated.

Was it helpful?

Solution

inds = ~cellfun('isempty', elem);    %// NOTE: faster than anonymous function
conn = conn(inds,:);
elem = elem(inds);                   %// (preservative)

or

inds = cellfun('isempty', elem);     %// NOTE: faster than anonymous function
conn(inds,:) = [];
elem(inds  ) = [];                   %// (destructive)

or

inds = cellfun(@(x)isequal(x,[]), elem)  %// NOTE: stricter; evaluates to false 
conn = conn(inds,:);                     %// when the 'empties' are '' or {}
elem = elem(inds);                       %// or struct([])

or

inds = cellfun(@(x)isequal(x,[]), elem)  %// "
conn(inds,:) = [];
elem(inds  ) = [];

or

inds = cellfun(@numel, elem)==2    %// NOTE: even stricter; only evaluates to 
conn = conn(inds,:);               %// true when there are exactly 2 elements 
elem = elem(inds);                 %// in the entry

or

inds = cellfun(@numel, elem)==2    %// " 
conn(inds,:) = [];
elem(inds  ) = [];

or (if you're just interested in elem)

elem = cell2mat(elem)

or

elem = cat(1,elem{:})  %// NOTE: probably the fastest of them all

OTHER TIPS

Your first output can be obtained by:

cellfun(@fliplr, elem(~cellfun(@isempty, elem)), 'UniformOutput', 0);

Note that I included @fliplr, assuming that the element order reversal in your question was intentional

Your second output can be obtained by:

conn(~cellfun(@isempty, elem), :);
conn = [1   2
        1   3
        1   4
        1   5
        2   3
        2   4
        2   5
        3   4
        3   5
        4   5];

elem = { [36 29]
         []
         [30 29]
         [30 18]
         []
         [31 29]
         []
         [8 9]
         [32 30]};

conn(~cellfun(@isempty, elem), :)

you can use the @isempty function for cellfun() together with logical operators like this:

EmptyCells=cellfun(@isempty,elem); %Detect empty cells

elem(EmptyCells)=[]; %Remove empty cells

conn=conn(~EmptyCells); %Remove elements corresponding the empty cells in elem

Hope that works!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top