How do I find a specific cell within a cell array? - matlab

Let's say I have a cell array containing 1x2 cells. eg. deck = {{4,'c'},{6,'s'}...{13,'c'}...{6,'d'}}
How can I find the index of a specific cell? E.g I want to find the index of the cell with the values {13,'c'}.
Thanks!

Try cellfun with isequal:
>> deck = {{4,'c'},{6,'s'},{13,'c'},{6,'d'}};
>> targetCell = {13,'c'};
>> found = cellfun(#(c) isequal(c,targetCell),deck)
found =
0 0 1 0
cellfun let's you check anyway you want (not just isequal). For example, if you want to check based on the string element in each cell:
>> targetLetter = 'c';
>> found = cellfun(#(c) strcmp(c{2},targetLetter),deck)
found =
1 0 1 0

Another method I can suggest is to operate on each column separately. We could use logical operators on each column to search for cards in your cell array that contain a specific number in the first column, followed by a specific suit in the second column. To denote a match, we would check to see where these two outputs intersect. We can do this by combining both outputs with a logical AND when we're done:
deck = {{4,'c'},{6,'s'},{13,'c'},{6,'d'}};
target_card = {13, 'c'};
deck_unroll = vertcat(deck{:});
a1 = cat(1, deck_unroll{:,1}) == target_card{1};
a2 = cat(1, deck_unroll{:,2}) == target_card{2};
found = a1 & a2
found =
0
0
1
0
Because deck is a nested cell array, I unrolled it so that it becomes a 2D cell array where each row denotes one card. This is stored in deck_unroll. Once I do this, I further unroll the cells so that the first column gets placed into a numeric array and we search for a particular number (13 in your example) and the second column gets placed into a string array where we search for a particular character ('c' in your example). This is done with the help of cat to extract each element from a particular column and we construct an array out of these elements.

Related

How to find an matching element (either number or string) in a multi level cell?

I am trying to search a cell of cell arrays for a matching number (for example, 2) or string ('text'). Example for a cell:
A = {1 {2; 3};4 {5 'text' 7;8 9 10}};
There is similar question. However, this solution works only, if you want to find a number value in cell. I would need a solution as well for numbers as for strings.
The needed output should be 1 or 0 (the value is or is not in the cell A) and the cell level/deepness where the matched element was found.
For your example input, you can match character vectors as well as numbers by replacing ismember in the linked solution with isequal. You can get the depth at which the search value was found by tracking how many times the function has to go round the while loop.
function [isPresent, depth] = is_in_cell(cellArray, value)
depth = 1;
f = #(c) isequal(value, c);
cellIndex = cellfun(#iscell, cellArray);
isPresent = any(cellfun(f, cellArray(~cellIndex)));
while ~isPresent
depth = depth + 1;
cellArray = [cellArray{cellIndex}];
cellIndex = cellfun(#iscell, cellArray);
isPresent = any(cellfun(f, cellArray(~cellIndex)));
if ~any(cellIndex)
break
end
end
end
Using isequal works because f is only called for elements of cellArray that are not themselves cell arrays. Use isequaln if you want to be able to search for NaN values.
Note this now won't search inside numeric, logical or string arrays:
>> A = {1 {2; 3};4 {5 'text' 7;8 9 [10 11 12]}};
>> is_in_cell(A, 10)
ans =
logical
0
If you want that, you can define f as
f = #(c) isequal(value, c) || isequal(class(value), class(c)) && ismember(value, c);
which avoids calling ismember with incompatible data types, because of the 'short-circuiting' behaviour of || and &&. This last solution is still a bit inconsistent in how it matches strings with character vectors, just in case that's important to you - see if you can figure out how to fix that.

how to find row from numeric cell that contain target vector in Matlab?

I have cell array that is as follow:
S{1} = [10,20,30,40,50];
S{2} = [10,20,40,50];
S{3} = [10,50,510];
S{4} = [10,20,70,40,60];
S{5} = [20,40];
and,i have a target vector:
T=[10,70]
i need to find rows of cell that T is subitem of those.
for above example result is : 4
because T is subitems of row 4.
Get the count of matches for each cell against T and see which cells have a match count being equal to the number of elements in T, indicating that those cells have all elements from T. The assumption here is that we have unique elements in each of those cells.
Here's the implementation -
find(cellfun(#(x) nnz(ismember(x, T)), S) == numel(T))
Or as suggested by #Leander Moesinger we can get the matches for each element off T across all elements in each cell and then simply use all(), like so -
find(cellfun(#(x) all(ismember(T,x)),S))

subindex into a cell array of strings

I have a 6 x 3 cell (called strat) where the first two columns contain text, the last column has either 1 or 2.
I want to take a subset of this cell array. Basically select only the rows where the last column has a 1 in it.
I tried the following,
ff = strat(strat(:, 3), 1:2) == 1;
The error message is,
Function 'subsindex' is not defined for values of class 'cell'.
How can I index into a cell array?
Cell arrays are accessed through braces {} instead of parentheses (). Then, as a 2nd subtlety, when pulling values out of a cell arrays, you need to gather them...for numerics you gather them into regular arrays using [] and for strings you gather them into a new cell array using {}. Confusing, eh?
ff = { strat{ [strat{:,3}]==1 , 1:2 } };
Gathering into cell arrays this way can often give the wrong shape when you're done. So, you might try something like this
ind = find([strat{:,3}]==1); %find the relevant indices
ff = {{strat{ind,1}; strat{ind,2}}'; %this will probably give you the right shape

Combine Columns of Cell Array Matlab

I have a 2D cell array with dynamic row sizes and column sizes. One example:
cell3 = [{'abe' 'basdasd' 'ceee'}; {'d' 'eass' 'feeeeeeeeee'}]
Gives: (with dimension 2 by 3)
'abe' 'basdasd' 'ceee'
'd' 'eass' 'feeeeeeeeee'
I want to be able to combine the columns and reproduce a aggregate string cell array where each string is separated by a single white space. Any idea how to do that?
So the output i am looking for is:
'abe basdasd ceee'
'd eass feeeeeeeeee'
The final dimension is 2 by 1.
Is this possible?
Apply strjoin either in a loop or via cellfun. The latter:
>> cellRows = mat2cell(cell3,ones(size(cell3,1),1),size(cell3,2));
>> out = cellfun(#strjoin,cellRows,'uni',0)
out =
'abe basdasd ceee'
'd eass feeeeeeeeee'
Solution without loops or cellfun:
[m n] = size(cell3);
cellCols = mat2cell(cell3,m,ones(1,n)); %// group by columns
cellColsSpace(1:2:2*size(cell3,2)-1) = cellCols; %// make room (columns)...
cellColsSpace(2:2:2*size(cell3,2)-1) = {{' '}}; %// ...to introduce spaces
%// Note that a cell within cell is needed, because of how strcat works.
result = strcat(cellColsSpace{:});

Assign a row to cell array in Matlab?

I am trying to do this as with matrices:
>> line_params{1,:} = {numberPatterns{i}, lw, iw};
The right hand side of this assignment has too few values to satisfy the left hand side.
but getting error above.
Types are following:
>> class(line_params)
ans =
cell
>> size(line_params)
ans =
21 3
>> a={numberPatterns{i}, lw, iw};
>> class(a)
ans =
cell
>> size(a)
ans =
1 3
Change
line_params{1,:} = {numberPatterns{i}, lw, iw}
into
line_params(1,:) = {numberPatterns{i}, lw, iw}
(normal parenthesis).
If you use curly braces ({}), you reference the individual elements. That is,
line_params{1,:}
will return a comma-separated list of elements in the cell line_params in its first row. You cannot assign a cell array (single item) to a comma-separated list (multiple items).
If you use parenthesis (()), you reference the cell entry, i.e., a cell array will be returned. And you can assign a cell array (single item) to another cell array (single item) -- provided they have the same dimensions of course.