Reputation: 1858
I have a 2D cell array as follows:
my_cells=
Columns 1 through 11
{1x6 cell} {1x8 cell} {1x2 cell} {1x7 cell} {1x7 cell} {1x6 cell} {1x7 cell} {1x7 cell} {1x8 cell} {1x5 cell} {1x7 cell}
Columns 12 through 22
{1x4 cell} {1x3 cell} {1x3 cell} {1x5 cell} {1x5 cell} {1x4 cell} {1x3 cell} {1x5 cell} {1x4 cell} {1x5 cell} {1x4 cell}
Columns 23 through 24
{1x6 cell} {1x1 cell}
Each one of these cells has a number of arrays as follows:
my_cells{1}= [1x3 double] [1x3 double] [1x3 double] [1x3 double] [2x3 double] [1x3 double]
and
my_cells{1}{1}= [977.0000 1.0000 0.9231]
my_cells{1}{2}= [286.0000 7.0000 0.9789]
my_cells{2}{1}= [977.0000 1.0000 0.9231]
my_cells{3}{1}= [286.0000 7.0000 0.9789]
my_cells{1}{5}=[949.0000 7.0000 0.9241
474.0000 4.0000 0.9926]
I would like to find, for example, where else the number 977 might appear as a first element in my_cells
. However, I would like to avoid nested for loops to increase the performance if it is possible. Is there an easy and fast way to do it?
So the output would be something like 1,1,1 and 2,1,1.
An example that is not efficient looks like:
number=977;
for i=1:N
M=size(my_cells{i},2);
for j=1:M
[a,ind]=ismember(number,my_cells{i}{j}(:,1));
if sum(a)~=0
ind( ~any(ind,2), : ) = [];
my_cells{i}{j}(ind,2)=my_cells{i}{j}(ind,2)-1;
end
end
end
Upvotes: 2
Views: 254
Reputation: 25232
This should do it:
%// Value to check
a = 977;
%// indices of cells containing a at the first place
idx = cellfun(@(x) find(x == a,1) == 1, my_cells)
%// first cell containing a
cellsWith977atFirst = my_cells(idx)
For
my_cells = { [977 1 2] [2 977 977] [977 2 1] }
it will return
celldisp(cellsWith977atFirst)
cellsWith977atFirst{1} = 977 1 2
cellsWith977atFirst{2} = 977 2 1
But I just have seen that your input is actually:
my_cells = { {[977 1 2]} {[2 977 977]} {[977 2 1]} }
you should rethink, if this way of storing your data actually makes sense. You need to change the code for this case to:
idx = cellfun(@(x) find(cell2mat(x) == a,1) == 1, my_cells)
you noe could access my_cells
again by
cellsWith977atFirst = my_cells(idx);
but you may prefer this
cellsWith977atFirst = cellfun(@cell2mat, my_cells(idx), 'uni',0)
Maybe you need to vary the code a little depending on how exactly you wish your output.
Upvotes: 3