How do I flip the order of cells in a cell array?

If I have a cell array with a single row of cells of different sizes, e.g
cellarray = {3x2 double} {4x2 double} {5x2 double}
how can I flip the order of the arrays in the cell without flipping the individual elements - the outcome I want is
cellarray = {5x2 double} {4x2 double} {3x2 double}
but no change to the actual matrices in each cell. I thought this was the fliplr command but this doesn't work.

Answers (2)

Stephen23
Stephen23 on 6 Dec 2018
Edited: Stephen23 on 6 Dec 2018
Simpler:
C(end:-1:1) = C(:)
or
C = flip(C)
However there are better solutions than this , try :
result=cell(1,numel(cellarray));
ctr=1;
for i =numel(cellarray):-1:1
result{ctr}=cellarray{i};
ctr=ctr+1;
end
result

11 Comments

This isn't working correctly for how my code is formatted - I have a loop that creates a nx2 array and saves it into a cell. So each time through the loop I have an array which I store in a cell array using cell{kk} = array.
The format of this cell array is a 1x50 cell array containing 50 cells of size nx2. So my variable cellarray is the entries found inside a 1x50 cell array.
can you upload your cellarray as a .mat file?
Not easily - I tried to change the loop so that it took the last set of data first and went backwards, as I thought this should put the elements into the array in the reverse order, but nothing changed. Should I expect it to go the opposite way?
Have no clue what you are talking about without knowing how the data is stored
D = uigetdir
cd(D);
N = 13;
Index = 1:13;
SpectrumFileInfo = dir('Spectrum Data*');
SpectrumFileInfo=SpectrumFileInfo(Index);
NSpec = length(SpectrumFileInfo);
peakposarray = zeros(N,50); % 50 is for the number of currents
numpeaksarray = zeros(N,50);
for k = 1:NSpec % loop through each folder in directory
FolderName = SpectrumFileInfo(k).name;
Direc = dir([FolderName '\I*.csv']);
[~,idx] = sort([Direc.datenum]);
Direc = Direc(idx);
DataPointsSpec = length(Direc)-2;
for kk = DataPointsSpec+1:-1:2 % loop through each file in each folder from high to low current
SpectrumData = PeakFit([FolderName '\' Direc(kk).name]); % atm this just does csvread
Wavelength=SpectrumData(2:end-1,1); %ignore first and last point
Intensity=SpectrumData(2:end-1,2);
% peak fitting function - fits up to 6 peaks
[pks locs w]=findpeaks(Intensity,'NPeaks',6,'MinPeakDistance',4); % seems about the right parameters to only get the modes and no other noise peaks
elim = find(pks<0.002); % finds location in array of peaks with low intensity (to be ignored)
pks(elim)=[]; % deletes low intensity peaks
numpeaks = length(pks) % number of peaks
numpeaksarray(k,kk) = numpeaksarray(k,kk)+numpeaks; % makes array of number of peaks
lambda = Wavelength(locs); % wavelength of each peak
lambda(elim)=[]; % deletes wavelengths of low intensity peaks
if isempty(lambda)
vec = zeros(1,2); % eliminates problems coming from data sets with no peaks
else
vec = [lambda,pks]; % Makes a matrix of peak position and height
end
vecarray{kk} = vec % saves each iteration in a cell
end
end
I have included two files - these would normally be saved in a folder called Spectrum Data*. The problem comes with vecarray{kk} - the order of the cells is the same whether or not I do the second loop as for kk = DataPointsSpec+1:-1:2 or kk=2:DataPointsSpec. This doesn't seem correct but I have tried clearing all variables and nothing seems to enter the cells in the correct order.
Assuming what you want is exactly what you've described in the question, it's trivial to do. See Stephen's answer.
Well I thought it should be easy but it doesn't seem to work when I enter that.
"Well I thought it should be easy but it doesn't seem to work when I enter that."
Then most likely you did something wrong (or your original question does not explain the situation completely). Show us exactly what you tried that "does not seem to work".
Note that you should avoid using cd like that: it is slow and makes debugging harder. It is much better to use absolute/relative filenames.
I added the command vec = flip(vec) after vecarray{kk} = vec, which flipped the elements in each matrix such that the last row became the first row etc and stored as an array not a cell.
I think there is something strange happening when the cell is created - if I add the commands
vecarray{kk} = vec
vec
vecarray{end}
I find that vecarray{kk} prints the cells in the order that I stated that I wanted to change in my first comment - so that the 3x2 element is first. If I then print vec directly after that in the same loop, I get a 5x2 matrix. If I print vecarray{end} I get a 3x2 matrix. I'm not sure how this can happen as it seems to have the same thing stored in the opposite order.
"I think there is something strange happening when the cell is created "
There is nothing strange happening at all. MATLAB is doing exactly what you tell it to do. Just because you reverse the order which you put the values into the cells makes no difference to the indices that you are using. These two loops will create exactly the same arrays with the same data in the same locations:
C = nan(1,5);
for k = 5:-1:1 % assign in descending order
C(k) = k^2;
end
D = nan(1,5);
for k = 1:5 % assign in ascending order
D(k) = k^2;
end
Just because we define element 5 first, it does not somehow become that 1st element of the array. Nope. The 5th element is always the 5th element, which is fixed by the indexing, not by which one we define first. To allocate to a different element, you need to change the indexing (e.g. as madhan ravi showed you).
So your comparison:
vecarray{kk} = vec
vec
vecarray{end}
tells us nothing until you check what value kk has: is it the same as numel(vecarray) (equivalent to end when used as an index) ? Judging by your code the answer is "no". So do they refer to the same cell? (hint: "no")

Sign in to comment.

Asked:

JJH
on 6 Dec 2018

Edited:

on 7 Dec 2018

Community Treasure Hunt

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

Start Hunting!