Search entire multi level cell array for matching string

26 次查看(过去 30 天)
I am trying to search a cell of cell arrays for a matching string without using a for loop due to the inefficiency and speed. My first idea was to use an anonymous function and strip out the top layer iteratively of the cell array in the form of
cellfun(@(cell) cell{1}, MyCellofCellArray, 'UniformOutput', false);
However, let's say for example I have an uneven cell of cell array where
MyCellArray{1} = 1x1 cell,
MyCellArray{2} = 1x2 cell,
MyCellArray{3} = 1x3 cell.
If you try to use the aforementioned cellfun, you get an error "Index exceeds matrix dimensions" because MyCellArray{1} only contains a 1x1 cell. Anyone have any ideas or suggestions?
Thanks,
JWelch
  3 个评论
Josh Welch
Josh Welch 2015-8-6
I just need to extract the index of the array element of the matching string. Each element of the array contains just one string.
i.e. MyCellArray{1} = {'str11'}, MyCellArray{2} = {'str21','str22'}, MyCellArray{3} = {'str31','str32','str33'}. I would like to find the indices of cell 'str32' in MyCellArray. The element is accessed via MyCellArray{3}{2} so 3, 2 would be the answer.
Cedric
Cedric 2015-8-6
编辑:Cedric 2015-8-6
Which version of MATLAB do you have? Also, are you search for unique keywords, for the first when there are multiple, or for all occurrences?

请先登录,再进行评论。

采纳的回答

James Tursa
James Tursa 2015-8-6
编辑:James Tursa 2015-8-6
Does this do what you want?
mystring = whatever string you are trying to find
MyCellArrays = [cellfun(@(x)x(:)',MyCellArray,'UniformOutput',false)];
NewCellArrays = [MyCellArrays{:}];
x = find(~cellfun(@isempty,strfind(NewCellArrays,mystring)));
n = cellfun(@numel,MyCellArray);
nsum = cumsum(n);
first = find(nsum>=x,1);
if( first == 1 )
second = x;
else
second = x - nsum(first-1);
end
The element is then MyCellArray{first}{second}
If the string is not guaranteed to be present, then test for x being empty before executing the remaining code.
  1 个评论
Josh Welch
Josh Welch 2015-8-6
This code actually will work. I was hoping to get the indices from the original matrix but I can massage the rest of my code the same way to get the corresponding data with the same indices.
Thanks for your help!

请先登录,再进行评论。

更多回答(1 个)

Cedric
Cedric 2015-8-6
编辑:Cedric 2015-8-6
If you have 2015a or above, this can be an occasion for playing with the new REPELEM function:
linId = strcmpi( [MyCellArray{:}], 'str32' ) ;
lookup = repelem( 1:numel(MyCellArray), cellfun( @numel, MyCellArray )) ;
id = [lookup(linId), sum( lookup(1:find(linId) == lookup(linId)) )] ;
This produces
id =
3 2
  2 个评论
Josh Welch
Josh Welch 2015-8-6
I tried this code which is extremeley elegant, but I don't have 2015. When I upgrade, REPELEM is definitely going in my bag of tricks... thanks for your input
Cedric
Cedric 2015-8-6
编辑:Cedric 2015-8-6
My pleasure! I discovered REPELEM last week actually, so I'm glad to have had this occasion for playing a bit with it. Just for those who don't have 2015a or above, here is the output of intermediary steps:
linId =
0 0 0 0 1 0
lookup =
1 2 2 3 3 3

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Variables 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by