Фильтрация массива ячеек с помощью рекурсии

Я довольно близок к этой проблеме. Что мне нужно сделать, так это отфильтровать массив ячеек. Массив ячеек может содержать множество элементов, но я хочу вытащить строки, используя рекурсию. Я довольно близок к этому. У меня просто проблема, когда в ячейках есть пробелы. Вот что я должен получить:

 Test Cases:

       cA1 = {'This' {{{[1:5] true} {' '}} {'is '} false true} 'an example.'};
       [filtered1] = stringFilter(cA1)
           filtered1 => 'This is an example.'

       cA2 = {{{{'I told '} 5:25 'her she'} {} [] [] ' knows'} '/take aim and reload'};
       [filtered2] = stringFilter(cA2)
           filtered2 => 'I told her she knows/take aim and reload'

Вот что у меня есть:

%find the strings in the cArr and then concatenate them. 
function [Str] = stringFilter(in)
Str = [];
for i = 1:length(in)
    %The base case is a single cell
    if length(in) == 1
        Str = ischar(in{:,:});
    %if the length>1 than go through each cell and find the strings. 
       else
        str = stringFilter(in(1:end-1));
        if ischar(in{i})
            Str = [Str in{i}];
    elseif iscell(in{i}) 
            str1 = stringFilter(in{i}(1:end-1));
            Str = [Str str1];

        end
    end

end

end

Я пытался использовать ismember, но это не сработало. Какие-либо предложения? Мой код выводит следующее:

      filtered1 => 'This an example.'
      filtered2 => '/take aim and reload'

person Jessica Marie    schedule 31.10.2014    source источник


Ответы (3)


Вы можете довольно упростить свою функцию до

function [Str] = stringFilter(in)
Str = [];
for i = 1:length(in)
    if ischar(in{i})
        Str = [Str in{i}];
    elseif iscell(in{i})
        str1 = stringFilter(in{i});
        Str = [Str str1];
    end
end

end

Просто переберите все элементы в ячейке теста, будь то строка или ячейка. В последнем снова вызовите функцию для этой ячейки. Выход:

>> [filtered1] = stringFilter(cA1)

filtered1 =

This is an example.

>> [filtered2] = stringFilter(cA2)

filtered2 =

I told her she knows/take aim and reload
person Nemesis    schedule 31.10.2014
comment
OKay, это действительно имеет смысл :) Спасибо! - person Jessica Marie; 31.10.2014

Вот другая реализация

function str = stringFilter(in)
if ischar(in)
    str = in;
elseif iscell(in) && ~isempty(in)
    str = cell2mat(cellfun(@stringFilter, in(:)', 'uni', 0));
else
    str = '';
end
end

Если это строка, верните ее. Если это ячейка, примените одну и ту же функцию ко всем элементам и соедините их. Здесь я использую in(:)', чтобы убедиться, что это вектор-строка, а затем cell2mat объединяет полученные строки. И если тип любой другой, верните пустую строку. Нам нужно проверить, пуст ли массив ячеек или нет, потому что cell2mat({}) имеет тип double.

person Mohsen Nosratinia    schedule 31.10.2014
comment
Я это понимаю, но обычно Cell2mat недоволен тем, что нас не научили им пользоваться. - person Jessica Marie; 31.10.2014

Линия

    Str = ischar(in{:,:});

это проблема. Для меня это не имеет никакого смысла.

Вы близки к получению ответа, но допустили несколько существенных, но небольших ошибок.

Вам нужно проверить следующие вещи: 1. Перебрать ячейки ввода. 2. Для каждой ячейки проверьте, является ли она сама ячейкой, если да, вызовите stringFilter для ЗНАЧЕНИЯ ячейки. 3. Если это не ячейка, а массив символов, то используйте его ЗНАЧЕНИЕ как есть. 4. В противном случае, если ячейка VALUE содержит несимвол, вклад этой ячейки в вывод равен '' (пусто)

Я думаю, вы допустили ошибку, не воспользовавшись разницей между in(1) и in{1}. Во всяком случае, вот моя версия функции. Оно работает.

function [out] = stringFilter(in)
out = [];

for idx = 1:numel(in)
    if iscell (in{idx})
        % Contents of the cell is another cell array
        tempOut = stringFilter(in{idx});
    elseif ischar(in{idx})
        % Contents are characters
        tempOut = in{idx};
    else
        % Contents are not characters
        tempOut = '';
    end

    % Concatenate the current output to the overall output
    out = [out, tempOut];
end

end
person Akshay Rao    schedule 31.10.2014
comment
Это тоже имеет смысл, спасибо :) - person Jessica Marie; 31.10.2014