Afzaal Ahmad
Afzaal Ahmad

Reputation: 197

Generalized method for deletion of any integer from cell arrays after comparisons in matlab?

This is a follow up question of How to delete element from cell arrays after comparisons without causing cell arrays to get empty? for which i got a partial solution. following is the code:

A = cell(2);
A{1} = [2 4];
A{3} = [3 2 0];
A{4} = 1;
celldisp(A) % A contains one 2, an empty cell, a double array and a 1.

AWithout2ButNotEmptied = cellfun(@(x) x( (x~=2) | (numel(x)<2) ), A,'UniformOutput', false);
celldisp(AWithout2ButNotEmptied)

output of above code is:

A{1,1} =
 2 4
A{2,1} =
 []
A{1,2} =
 3     2     0
A{2,2} =
 1
AWithout2ButNotEmptied{1,1} =
 4
AWithout2ButNotEmptied{2,1} =
 []
AWithout2ButNotEmptied{1,2} =
 3     0
AWithout2ButNotEmptied{2,2} =
 1

output shows that A{1,1} is equal to 4 and is not emptied after deletion of 2, because its length is less than two (its length is one). A{1,2} has the element equal to 2 removed. A{2,1} is already empty and is left unchanged. A{2,2} has length 1, but is not equal to 2, so it is left unchanged as well so, the check is performed only on number 2 whether to be deleted or not.

How can i change this code to remove any number x(not only 2) from any cell element if it does not causes any other array to become empty.

I want to do this for any value of x(1,...,n) in my cell i don't want to remove any specific numbers it could be any number x from the cell arrays.

for example:

OccursTogether{1,1} =

4 11 14

OccursTogether{1,2} =

1
OccursTogether{1,3} =

[]
OccursTogether{1,4} =

1 4 8 14 15 19 20 22

OccursTogether{1,5} =

 4 11

the result i want is as follows;

OccursTogether{1,1} =

 11

OccursTogether{1,2} =

1
OccursTogether{1,3} =

[]
OccursTogether{1,4} =

1 8 15 19 20 22

OccursTogether{1,5} =

 11

as u can see 4 and 14 is removed from multiple cells which gave the above result. we cannot remove 11 because it will cause empty location at {1,1} and {1,5} same checks should be applied on every number x before removing it.

Upvotes: 3

Views: 75

Answers (1)

Erik
Erik

Reputation: 4573

My answer to your previous question is updated now.

I copied it here:


Use the following, where C stands for your OccursTogether cell (shorter, thus easier to read for this answer). The comments in the code explain a bit what the corresponding lines do.

C = cell(3,2);

C{1,1} = [4 11 14];
C{2,1} = 1;
C{2,2} = [1 4 8 14 15 19 20 22];
C{3,2} = [4 11];
celldisp(C)

C = cellfun(@unique, C, 'UniformOutput', false); % remove duplicates from elements of C

numsInCell = unique([C{:}]); % numbers in cell, sorted

for n = numsInCell % loop over numbers in cell
    lSetIs1 = cellfun(@numel,C) == 1; % length of set is 1
    nInSet = cellfun(@(set) any(set==n), C); % set contains n
    nIsUnique = sum(nInSet(:))==1; % n occurs once
    condition = ~nIsUnique & ~any(nInSet(:) & lSetIs1(:)); % set neither contains n and has length of 1, nor n is unique
    if condition % if false for all sets...
        C = cellfun(@(set) set(set~=n), C, 'UniformOutput', false); % ... then remove n from all sets
    end
end

celldisp(C)

Notice I use logical indexing in the line in the for-loop starting with C = cellfun(..., which saves you an additional for-loop over the elements of C. The MATLAB function cellfun performs the function handle in its first argument on the elements of the cell in the second argument. This is a very useful tool that prevents the use of many for-loops and even some if-statements.

Upvotes: 1

Related Questions