Find the cell index in a nested cell array, corresponding to a string (by using strcmp)

I have a 1×2 nested cell array A (cell array within a cell array):
A =
1×2 cell array
{43612×7 cell} {863892×7 cell}
where
A{1} =
{'Up' } {'Down' } {'Left' } {'Right'} {'BLUE'}
{'1' } {'7' } {'1' } {'8' } {'3' }
{'2' } {'7' } {'4' } {'3' } {'7' }
{'9' } {'1' } {'6' } {'2' } {'1' }
{'...' } {'...' } {'...' } {'...' } {'...' }
A{2} =
{'Up' } {'Down' } {'Left' } {'Right'} {'RED' }
{'2' } {'1' } {'1' } {'1' } {'2' }
{'6' } {'1' } {'7' } {'4' } {'2' }
{'5' } {'9' } {'8' } {'4' } {'4' }
{'...' } {'...' } {'...' } {'...' } {'...' }
If possible, by using only 1 or 2 lines of code, I would like to know if the text 'BLUE' is in A{1} or in A{2}.
The full answer would be: 'BLUE' is in A{1}(1,5), but I would like to know just the first index of A, i.e. either A{1} or A{2}.
Therefore, if we consider only the firs index of A, i.e. either A{1} or A{2}, my Result would be something like:
Result = 2x1 logical array
1
0
Which means my 'BLUE' text is in A{1}.
My first attempt started by using 'strcmp' in this way:
cellfun(@(x) strcmp(x, 'BLUE'), A, 'UniformOutput', false)
But then I got stuck... Any suggestion to get what I need in only 1 or 2 lines of code ?
Hope my question is clear enough.... Thanks a lot and best regards!

 Risposta accettata

B=cellfun(@(x) strcmp(x, 'BLUE'), A, 'UniformOutput', false);
cellfun(@(c) any(c(:)), B)

1 Commento

Edit:
B = cellfun(@(x) strcmp([x{:}], 'BLUE'), A, 'UniformOutput', false);
cellfun(@(c) any(c(:)), B)

Accedi per commentare.

Più risposte (3)

A{1} = { ...
{'Up' } {'Down' } {'Left' } {'Right'} {'BLUE'}
{'1' } {'7' } {'1' } {'8' } {'3' }
{'2' } {'7' } {'4' } {'3' } {'7' }
{'9' } {'1' } {'6' } {'2' } {'1' }
{'...' } {'...' } {'...' } {'...' } {'...' }}
A{2} = {...
{'Up' } {'Down' } {'Left' } {'Right'} {'RED' }
{'2' } {'1' } {'1' } {'1' } {'2' }
{'6' } {'1' } {'7' } {'4' } {'2' }
{'5' } {'9' } {'8' } {'4' } {'4' }
{'...' } {'...' } {'...' } {'...' } {'...' }}
% testfun (ONELINE function)
% EDIT version
% returns 1 x 2 boolean arrays B, B(i) is TRUE if word exists in A{i}
testfun = @(word) ismember([0 1],find(strcmp([A{1}{:} A{2}{:}], word))>numel(A{1}));
testfun('BLUE')
testfun('RED')
testfun('Up')
testfun('YELLOW')
testfun('3')
testfun('5')
Here is a one-liner:
cellfun(@(y)any(any(cellfun(@(x)isequal(x,{'BLUE'}),y))),A)
I stumbled across this function for dealing with nested cell arrays. I did not try it myself, but it could make this a bit more elegant-looking.
Dear All,
Thanks a lot for your help!
I tried all the solutions proposed (so far) by Matt J, Bruno Luong and the cyclist:
clear all; clc;
A{1} = { ...
{'Up' } {'Down' } {'Left' } {'Right'} {'BLUE'}
{'1' } {'7' } {'1' } {'8' } {'3' }
{'2' } {'7' } {'4' } {'3' } {'7' }
{'9' } {'1' } {'6' } {'2' } {'1' }
{'...' } {'...' } {'...' } {'...' } {'...' }};
A{2} = {...
{'Up' } {'Down' } {'Left' } {'Right'} {'RED' }
{'2' } {'1' } {'1' } {'1' } {'2' }
{'6' } {'1' } {'7' } {'4' } {'2' }
{'5' } {'9' } {'8' } {'4' } {'4' }
{'...' } {'...' } {'...' } {'...' } {'...' }};
% Matt J
tic
B = cellfun(@(x) strcmp(x, 'BLUE'), A, 'UniformOutput', false);
cellfun(@(c) any(c(:)), B)
toc
% Bruno Luong
tic
testfun = @(word) unique((find(strcmp([A{1}{:} A{2}{:}], 'BLUE'))>numel(A{1}))+1);
testfun('BLUE')
toc
% the cyclist
tic
cellfun(@(y)any(any(cellfun(@(x)isequal(x,{'BLUE'}),y))),A)
toc
I got as follows:
% Matt J
ans =
1×2 logical array
0 0
Elapsed time is 0.002689 seconds.
% Bruno Luong
ans =
1
Elapsed time is 0.004951 seconds.
% the cyclist
ans =
1×2 logical array
1 0
Elapsed time is 0.002189 seconds.
To me - If I did everything correctly - it looks like that the best answer in terms of elapsed time is that one proposed by the cyclist. Therefore, I would like to accept his/her answer.
I greatly appreciate all your ideas and I thank you all for your efforts and time.
Regards,
SL

5 Commenti

You must test on very small samples.
For large sample Matt's solution wins, hand down, as it does not need to form any intermediate data, and CELLFUN is applied on small cell array (1 x 2)
@Bruno Luong you are right....
I tried all the solutions on my original (and quite large) sample, getting this:
% Matt J
ans =
1×2 logical array
1 0
Elapsed time is 0.067109 seconds.
% Bruno Luong
ans =
0×1 empty double column vector
Elapsed time is 2.813477 seconds.
% the cyclist
ans =
1×2 logical array
0 0
Elapsed time is 16.357751 seconds.
The solution proposed by Matt J is by far faster than the other ones. Also, the Matt J's solution gives the correct answer with a [1 0] logical array for my large sample, but a not correct [0 0] logical array for the previous small sample. Quite the opposite is the solution offered by the cyclist: it resulted in a correct [1 0] logical array for the small sample, but it gave a not correct [0 0] logical array for my large sample. I am double checking everything, but I actually did a simple copy and past... I think I should accept the Matt J's answer.........
The edited answer by Matt J results in the correct [1 0] logical array for both the small and the large samples... I am gonna accept his answer... Thanks!
Matt edit his code and correct the BUG, now his code runs about the same time as mine.
clear
createfun = @(s) arrayfun(@(x) {sprintf('%d',x)}, ceil(1000*rand(s)), 'unif',0);
A{1}=createfun([43612 7]);
A{2}=createfun([863892 7]);
% Matt J
tic
B = cellfun(@(x) strcmp([x{:}], '123'), A, 'UniformOutput', false);
matt_r = cellfun(@(c) any(c(:)), B);
toc % Elapsed time is 4.430430 seconds.
tic
testfun = @(word) ismember([0 1],find(strcmp([A{1}{:} A{2}{:}], word))>numel(A{1}));
bruno_r = testfun('123');
toc % Elapsed time is 3.967751 seconds.
% the cyclist
tic
cyclist_r = cellfun(@(y)any(any(cellfun(@(x)isequal(x,{'123'}),y))),A);
toc % Elapsed time is 22.860207 seconds.
Edit fix createfun BUG (forget inner {...})
Thanks a lot Bruno! Yes, your solutions are very similar in terms of elapsed time... I could give an ex-aequo "accept answer" to both, but I dont know how to do it...Is that possible ?
Just a curiosity: what do you get as results for "matt_r", "bruno_r" and "cyclist_r" ?
Thanks again for these interesting solutions!

Accedi per commentare.

Richiesto:

Sim
il 16 Set 2019

Modificato:

il 16 Set 2019

Community Treasure Hunt

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

Start Hunting!

Translated by