Kyle
Kyle

Reputation: 55

Eliminate numbers in cell arrays recursively

I've been doing a homework (this is only a part) where I have to work with cell arrays recursively, for example:

{1,{2,{5,{6,{}}}}}

And I need to eliminate objects based on a property, i.e.:

p=@(x)(x<3)

The function name is filter_list(list,p) and the result of using it should be:

{1,{2,{}}}

The code is:

function [ list ] = filter_list( list,p )
if isempty(list)==1
    disp('holo');
    return;
else
    if p(list{1})==0
        disp('hola');
        list(1)=list{2}(1);
        list(2)=list{2}(2);
        list{2}=filter_list(list{2},p);
    else
        disp('hele')
        list{2}=filter_list(list{2},p);
    end        
end

But what I get with this code is:

{1,{2,{6,{}}}}

It only eliminates the first element of the array that meets the:

p(list{1}) == 0

requirement.

What do I do to fix this? Also, if I use an array larger than 4, it crashes as well.

Upvotes: 2

Views: 89

Answers (2)

knedlsepp
knedlsepp

Reputation: 6084

The part where you are removing the first element from the list is incorrect.

Instead of

list(1)=list{2}(1);
list(2)=list{2}(2);
list{2}=filter_list(list{2},p);

You should simply use:

list = filter_list(list{2},p);

It might be more clear if you go for the holistic approach:

function list = filter_list(list, p)
if ~isempty(list)
    if p(list{1}) 
        list = {list{1}, filter_list(list{2}, p)}; %// Keep head of list
    else
        list = filter_list(list{2}, p);            %// Only keep filtered tail
    end
end
end

Upvotes: 1

user1543042
user1543042

Reputation: 3440

You need to call the function recursively,

function [ list ] = filter_list( list,p )
    for i = numel(list):-1:1 %Go through the cell backwards
        if ~iscell(list{i}) %if the cell contains a scalar, vector or matrix
            list{i}(~p(list{i})) = []; %if the number does not follow the rule specified by p remove it
            if isempty(list{i}) %if there is nothing in the scalar/vector/matrix remove it
                list(i) = [];
            end
        else %if the cell doesn't contain a number call the function again
            list{i} = filter_list(list{i}, p);
        end
    end
end

Upvotes: 1

Related Questions