Find index of cells containing my string

Hi, I have a cell aray (40,000X1)in which every cell contains a string. I would like to find the indexes of the cells containing a specific string. I used the following: Index = strfind(Mycellarray, 'Bla'); I get the following error: ??? Error using ==> cell.strfind at 35 If any of the input arguments are cell arrays, the first must be a cell array of strings and the second must be a character array. What is wrong, in the help file strfind accepts cell arrays and a pattern...? Thank you

7 commentaires

Walter Roberson
Walter Roberson le 25 Fév 2011
What version are you using?
>> Mycellarray = {'hello';'what';'is';'Bla';'about'};
>> strfind(Mycellarray,'Bla')
ans =
[]
[]
[]
[1]
[]
I will wildly speculate that you have a cell array in which each element is a cell array that contains a string.
Jos (10584)
Jos (10584) le 25 Fév 2011
Are you really sure you have a cell array of strings? Check it with ISCELLSTR
If this is not true, then you need to convert it first to be able to use STRFIND. For instance, if Walter is right and you have a cell array of a cell array of strings,
C = { {'a'}, {'b'}, {'c'}, {'a'}, {'a'} }
iscellstr(C) % false !
% ... but in this particular case it is easy to convert:
C2 = [C{:}]
and perhaps STRCMP better suits your needs as it will return a logical array directly
strcmp(C2,'a')
New
New le 25 Fév 2011
Hi
Thank you for your answers. I used C2 = [C{:}] as advised but then still trying to get the list of Indices I used:
Index = strfind(C2,'bla')
I get a cell array in which every cell is either empty [] or 1 but no list of indices.
K.
I found out that if the cell has empty indexes it wont work. Example:
a =
'hey'
'oh'
[]
>> strfind(a,'hey')
??? Error using ==> cell.strfind at 35 If any of the input arguments are cell arrays, the first must be a cell array of strings and the second must be a character array.
>> a{3} = 'letsGo'
a =
'hey'
'oh'
'letsGo'
>> strfind(a,'hey')
ans =
[1]
[]
[]
It is not considered as a cell string if all the cells in the array have a string in them.
Jan
Jan le 22 Fév 2013
@Felipe: Exactly. A cell is a cell string, if it contains strings only. And STRFIND works on strings and cell strings only.
Hello, I have got a similar Problem.
- find(strcmp(rawdata,'ggiBoundaries1(1,1)'))
I want to find in rawdata the first entry of ggiBoundaries1. But it doesn't work. The error message is =
"0×1 empty double column vector".
When I enter "ggiBoundaries1(1,1)" the output is a char. Maybe that's the problem or not?
This is not an error message. It simply tells you, that the string is not found.
Are you really looking for the string 'ggiBoundaries1(1,1)' ? Or do you mean:
find(strcmp(rawdata, ggiBoundaries1(1,1)))
to search for occurrences of the first character of the variable ggiBoundaries1?
Please do not append a new question to an existing thread. Better open a new one. Thanks.

Connectez-vous pour commenter.

 Réponse acceptée

Jan
Jan le 29 Août 2023
Modifié(e) : MathWorks Support Team le 13 Nov 2024

119 votes

Do you want to search for 'bla' within the text in each element of the cell array, or for elements that are 'bla' exactly? If you explain this detail, then your question would be easier to answer. If you are searching for text that has 'bla' as part of the text, then starting in R2016b you can use the “contains” function, as Alexander Cranney pointed out. Index = find(contains(C,'bla')); The function "contains" returns a logical array. This type of logical indexing can be used to make many workflows more efficient. For more on using logical arrays, refer to the documentation: https://www.mathworks.com/help/matlab/math/array-indexing.html#MatrixIndexingExample-3 https://www.mathworks.com/help/matlab/matlab_prog/find-array-elements-that-meet-a-condition.html In previous versions of MATLAB (before R2016b), you can use the “strfind” function. However, “strfind” returns a cell array of indices. For any input cell whose text does not contain 'bla', “strfind” returns an empty cell. Use “isempty” and “cellfun” with the “find” function to find the empty cells. IndexC = strfind(C,'bla'); Index = find(not(cellfun('isempty',IndexC))) If you are searching for text that is exactly 'bla', then see Jos’ answer.

10 commentaires

Walter Roberson
Walter Roberson le 26 Fév 2011
Possibly bla might occur multiple times and the indices of all of the positions is what is desired?
A little correction to Jan's answer:
IndexC = strfind(C, 'bla'); % not C2
...
No need to convert C into string from cell : C2 = [C{:}];
Alexander Cranney
Alexander Cranney le 6 Mar 2017
Modifié(e) : Alexander Cranney le 6 Mar 2017
As of MATLAB 2016b, there is a new function "contains" that does exactly this!
% code
Index = find(contains(C,'bla'));
xiangxue wang
xiangxue wang le 5 Nov 2017
Just to add my experience of running this. If the cell C contains some entry will NaN, it will gave the error like "First argument must be a string array, character vector, or cell array of character vectors" make sure your cell doesn't contain NaN
Duc Minh Nguyen
Duc Minh Nguyen le 12 Juin 2018
Modifié(e) : Duc Minh Nguyen le 12 Juin 2018
This answer will cause problem if there are other strings containing 'bla' in the array. For exact searching, use strcmp instead:
idx = find(strcmp(C, 'bla'))
Jan
Jan le 12 Juin 2018
@Duc Minh Nguyen: As said in the answer, it is the purpose of the code to find any occurrences of 'bla', not just the string 'bla'.
ANA ROSHAN
ANA ROSHAN le 10 Fév 2020
it was very useful. thanks!
Nnamdi Njoku
Nnamdi Njoku le 22 Mai 2020
Just what i needed, thanks
Aditi Bishnoi
Aditi Bishnoi le 22 Jan 2021
what to use if I want to find the exact string match 'bla'.
My cell array has both 'bla' and 'blah' elements, but i want to pick out only 'bla'.
Walter Roberson
Walter Roberson le 22 Jan 2021
Modifié(e) : Walter Roberson le 22 Jan 2021
exact_match_mask = strcmp(YourCell, 'bla')
exact_match_locations = find(exact_match_mask)
provided that your cell entries are all character vectors.

Connectez-vous pour commenter.

Plus de réponses (7)

Jay
Jay le 28 Mai 2016
Modifié(e) : Jay le 28 Mai 2016
This worked for me:
idx = find(ismember(C, 'bla'))

8 commentaires

Great! Works clean. Thanks.
Cameron Kimbrough
Cameron Kimbrough le 10 Oct 2016
Nice, just what I was looking for.
And this is faster, too. On my lenovo T460s, a search of a 3000-long cellstring takes about 0.5ms, compared with 2ms with
idx = find(contains(C,'bla'))
juliette Grimaldi
juliette Grimaldi le 20 Déc 2017
Great, thanks! Old stuff still makes it !
Einat
Einat le 5 Juin 2019
Yes! Worked just like I needed it to.
ANKUR WADHWA
ANKUR WADHWA le 17 Jan 2020
Modifié(e) : per isakson le 22 Mai 2020
Doesn't work on this one
C = { {'a'}, {'b'}, {'c'}, {'a'}, {'a'};{'b'}, {'a'}, {'c'}, {'a'}, {'c'} }
idx = find(strcmp([C{:}], 'a'))
Returns
idx = 1 4 7 8 9
Any suggestion on how to solve it.
It works as documented.
Matlab uses column-major order. (I fail to find a page to link to in the documentation.)
Try
%%
C = { {'a'}, {'b'}, {'c'}, {'a'}, {'a'}
{'b'}, {'a'}, {'c'}, {'a'}, {'c'} };
%%
cac = [C{:}]
idx = find(strcmp( cac, 'a' ))
%%
C1 = permute( C, [2,1] ); % switch rows and columns
idx = find(strcmp( [C1{:}], 'a' ))
it outputs
cac =
1×10 cell array
Columns 1 through 8
{'a'} {'b'} {'b'} {'a'} {'c'} {'c'} {'a'} {'a'}
Columns 9 through 10
{'a'} {'c'}
idx =
1 4 7 8 9
idx =
1 4 5 7 9

Connectez-vous pour commenter.

Jos (10584)
Jos (10584) le 25 Fév 2011
So, your original array was a cell array of cells with a single string. Use STRCMP and FIND to get the indices of the cells with a cell containing the specified string
C = { {'a'}, {'b'}, {'c'}, {'a'}, {'a'} } % data
idx = find(strcmp([C{:}], 'a')) % single line engine
Matt B
Matt B le 14 Nov 2013
I realize this question is old now, but a simple way of doing this is to define an inline function:
cellfind = @(string)(@(cell_contents)(strcmp(string,cell_contents)));
You can then use this with cellfun to return a boolean value for each element of the cell. For example:
cell_array={1,eye(2),true,'foo',10};
string='foo'
logical_cells = cellfun(cellfind('foo'),cell_array)
logical_cells =
[0,0,0,1,0]

3 commentaires

Sepp
Sepp le 27 Fév 2016
Great answer. Works very well.
josh gore
josh gore le 26 Jan 2017
The inline function was a life saver!
@Matt B: strcmp accepts a cell array directly, so you can avoid the complicated cellfun approach with the expensive anonymous function:
cell_array = {1,eye(2),true,'foo',10}
strcmp(cell_array, 'foo')
>> [0,0,0,1,0]

Connectez-vous pour commenter.

Omer Moussaffi
Omer Moussaffi le 26 Fév 2017

5 votes

Faster options: count startsWith endsWith
E,g, Index = count(Mycellarray, 'Bla');

1 commentaire

Walter Roberson
Walter Roberson le 26 Fév 2017
Yes, this method should work well starting from R2016b.

Connectez-vous pour commenter.

Jan
Jan le 25 Fév 2011
You can check if your cell is a cell string:
iscellstr(Mycellarray);
This displays the indices and contents of the non-strings:
Index = find(~cellfun('isclass', Mycellarray, 'char'))
disp(Mycellarray(Index));
Another idea is, that some strings are multi-row CHAR matrices:
Index = find(cellfun('size', Mycellarray, 1) > 1)
Peter Farkas
Peter Farkas le 9 Mai 2016

0 votes

You can also explicitelly define the index matrix:
[rw, ~] = size(cellArray);
ind = [1:1:rw];
idx = strcmp(cellArray, stringToSearchFor);
yourResult = ind(idx);
It is kind of verbose, if you review the code in 2 years time, you will still know what is going on.
Mukesh Jadhav
Mukesh Jadhav le 9 Oct 2016
Modifié(e) : per isakson le 10 Jan 2017
Haven't tested but this should work fine.
word_to_find=strfind(strarray,'stringtofind');
starray.index(word_to_find);

Catégories

En savoir plus sur Characters and Strings dans Centre d'aide et File Exchange

Tags

Aucun tag saisi pour le moment.

Community Treasure Hunt

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

Start Hunting!

Translated by