Sharath Chandra
Sharath Chandra

Reputation: 61

Rearranging Cell array containing strings

enter image description here

The contents in the cell array are as in the image showed above. I have two issues:

  1. I have to move cells in columns to the preceding ones wherever there are 0s. For example in row 1, the 1x7 cell has to come to the cell after 1x19 cell and so on.

  2. While doing this, the cells with [] should also be moved replacing the preceding 0s.

I tried using strncmp, ismember and other functions, but the 0 is throwing errors.

UPDATE with working code

The code is this:

It doesnt do all the work though. The cells being copied have to be deleted from the end.

for m=1:200
for i=1:46
    for j=1:199

        try
            if(tags{i,j}==0)
                for k=j:199
                    tags{i,k}=tags{i,k+1};
                    tags{i,k+1}='';
                end
            end
        catch exception

        end
    end
end
end

EDIT - Question's part 2 : Not solved yet

Each of the cells contains strings. Is there any way I can write them to a text file? All the strings in a cell have to be in the same line followed by a new line for the strings in the next cell.

Again, I tried this using a lot of functions, but I am unable to do it properly. I just get the first string in every cell to the text file.

Upvotes: 2

Views: 413

Answers (2)

Jonas
Jonas

Reputation: 74930

Here's an alternative approach: Instead of iterating over the array, create a new one and fill in only the non-zero values (note: if you want to avoid making a new array, you can, in the loop, create a temporary copy of the row, empty the row in the array, and overwrite). With some clever array shuffling, you could do step 3 without the loop entirely, btw.

%# step 1: find non-zeros
nonZeros = cellfun(@(x) ~iscell(x) && ~isempty(x), tags);

%# step 2: create new array with all empty
[nRows,nCols] = size(tags);
newTags = cell(nRows,nCols);

%# step 3: for every row: copy the non-zero entries
[goodRows,goodCols] = find(nonZeros);

for iRow = 1:nCols;
    myGoodCols = goodCols(goodRows==iRow);
    nGoodCols = length(myGoodCols);
    if nGoodCols > 0 && nGoodCols < nCols
       %# shift everything
       newTags(iRow, 1:nGoodCols) = tags(iRow,myGoodCols);
    end
end

%# step 4 : write out tags
fid = fopen('tags.txt','w+');
for iRow = 1:nRows
    for iCol = 1:nCols
        if ~isempty(tags{iRow,iCol})
        fprintf(fid,'row %i col%i : ',iRow,iCol);
        fprintf(fid,'%s ',tags{iRow,iCol}{:});
        fprintf(fid,'\n');
        end
    end
end

Upvotes: 1

The Minion
The Minion

Reputation: 1164

Edit 2
I guess the problem is that, your zeros weren't numbers but strings or chars as well. In that case just replace the if-arguments with a conversion from cell to matrix cell2mat as shown in the following code. Hopefully this solves your problem.

If not, could you post the code lines you used to create the zeros and other elements?

for k=1:200 %For looping on all columns 
    for i=1:46 %For  max rows
    try     
        if cell2mat(test_mat(1,i))== '0'
            test_mat{1,i}='';
            for j=i:46 % For max columns
              try
                if cell2mat(test_mat(1,j))~='0' 
                    test_mat{1,i}=test_mat{1,j};
                    test_mat{1,j}='';
                    break
                end
                catch exception
              end
            end

        end
    catch exception
    end
    end
end

Edit 1

 for k=1:200 %For looping on all columns 
    for i=1:46 %For  max rows
    try
        if test_mat{k,i}==0
            test_mat{k,i}='';
            for j=i:46 % For max columns
              try
                if test_mat{k,j}~=0 
                    test_mat{k,i}=test_mat{k,j};
                    test_mat{k,j}='';
                    break
                end
                catch exception
              end
            end
        end
    catch exception
    end
    end
 end

Hey this should know replace your elements correctly.
old Answer Hey not sure about 1 thing. But this should work

for k=1:max_row
   try
      if cell2mat(test_mat(1,k)) ==0 
         for j=k:max_row
           if cell2mat(test_mat(1,j)) ~= 0
               test_mat(1,k) = test_mat(1,j);
               test_mat(1,j) = {''};
               break
           end
         end
      end
      catch exception
   end
end

Here i am looping only through the first row (for all rows you could add another loop including this code). The first if checks if the element is 0. If so the second if checks for a non zero element in the same row but later column. Then i write that element into the 0 place and replace it with[].
I ain't sure if its an effective solution regarding runtime.
And the thing i ain't sure is your 7th line. What should happen there? Does the 3 non zero element <1x7>cell go to the <1x11>cell place, stays where it is or does it go back one slot?

Upvotes: 0

Related Questions