0

I have a cell array (n-by-1 dimension) containing both strings and cells, which looks something like this

{
{'r1'}     % -> cell content is in format 'char'
{'r2'}     % -> cell content is in format 'char'
{1x2 cell} % -> cell content is a cell array: [{'r1'}{'r2'}]
{'r3'}     % -> cell content is in format 'char'
{1x2 cell} % -> cell content is a cell array: [{'r1'}{'r3'}]
{1x2 cell} % -> cell content is a cell array: [{'r2'}{'r3'}]
{1x3 cell} % -> cell content is a cell array: [{'r1'}{'r2'}{'r3'}]
...
} 

I need to find the row-index where the some string is included, e.g. 'r2'. I usually use strfind for this purpose which works great if the cell array has a consistent format (hence 'char'-format within each cell).

Is there any way to apply this function to the cell array structure which is displayed above?

Thanks!

EDIT: Please find attached three images showing the data structure that I am using, since I am not sure how to exactly show/explain the hierarchies and layers of the cell array in text. Hope that helps. Also find attached the outcome of the code.

Code used:

change = 'r1.m';
srch = cellfun(@(x) strfind(x, change), strats, 'UniformOutput', false);
stringInRow = cellfun(@(x) numel(x) == 1 || (numel(x)>1)*numel(cell2mat(x))>0, srch);
rows = find(stringInRow);

cell array

example of cell array within cell 5,1

last "layer" in char format

outcome in 'srch'

outcome of logical operation on srch

0

1 Answer 1

3

You could use two subsequent cellfun calls: one to perform the string search (cell by cell), and one to evaluate it (found string true or not false?)

%// example data
c{1} = 'r1';     
c{2} = 'r2';    
c{3}{1} = 'r1'; c{3}{2} = 'r2';
c{4} = 'r3';
c{5}{1} = 'r1'; c{5}{2} = 'r3';

%// example search
searchForString = 'r2';
srch = cellfun(@(x) strfind(x, searchForString), c, 'UniformOutput', false);
stringInRow = ...
  cellfun(@(x) numel(x) == 1 || (numel(x)>1)*numel(cell2mat(x))>0, srch);
               %// ^-. short-circuit scalars here     ^
               %//                                    |
               %// since cell2mat is valid only for cells or empty arrays

With resulting stringInRow:

stringInRow =

     0     1     1     0     0

If you want to explicitly list the rows, you can just make use of find on the stringInRow boolean vector

>> foundStringInRows = find(stringInRow)

foundStringInRows =

     2     3
Sign up to request clarification or add additional context in comments.

12 Comments

a little mistake: looks like you mean use c{3}{2} second time instead of c{5}{2}. Can you clarify please, why searching in this cell array returns this answer? As I can see it mast be 0 1 1 0 0 because c{2}='r2' and c{3}{2} = 'r2'. So why it is 0 1 0 0 1?
I guess I beat you to fixing my own mistake (within 5 minutes also :) ) just prior to your comment. With this fix, search returns 0 1 1 0 0, as it should. Good catch though!
ahh, really! I have had to refresh it first! You are too fast ;D
thanks for the quick reply! The example works perfectly and does what I would like to achieve. However, when I apply it to my data and does not produce the correct results. The problem appears to be that when I produce search, all cells will contain another cell array (of different sizes). Any idea why this would happen?
@Benvaulter Are you sure that your data is a cell array, and not a single cell containing a cell array? If the latter, start by extracting the actual cell array (e.g. cArr = c{1}). If this is not the issue, please show us a fully verifiable example how (a subset) of your data looks like.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.