Split cell array taking into account difference between elements

1 view (last 30 days)
Hello! I have a cell array which contains indices from another cell array.Lets say for example
TES={[1;2;3;4;5];[12;13;14];[1;2;3;4;8;9;10;22;23;24];[4;5;6;8;9];[5;6;7]};
Where the indices have no jump at their sequence (cases 1,2 & 5) I want to keep the cell as it is. Where the jump is smaller than 2 I also want to keep the cell as it is(cell 4) But where there is a jump(or more) greater than 2 I need to split each cell into other cells.Their Number should be (jumbs+1).
The desirable result is
TES_new={[1;2;3;4;5];[12;13;14];[1;2;3;4];[8;9;10];[22;23;24];[4;5;6;8;9];[5;6;7]};

Accepted Answer

Guillaume
Guillaume on 3 Dec 2014
Edited: Guillaume on 3 Dec 2014
A fairly simple way of doing it:
TES={[1;2;3;4;5];[12;13;14];[1;2;3;4;8;9;10;22;23;24];[4;5;6;8;9];[5;6;7]};
runlengths = cellfun(@(m) diff([0; find(diff(m) > 2); numel(m)]), TES, 'UniformOutput', false);
splits = cellfun(@(m, runs) mat2cell(m, runs), TES, runlengths, 'UniformOutput', false);
TES_new = vertcat(splits{:})
You can combine both cellfun for a little bit more speed at the expense of readability:
splits = cellfun(@(m) mat2cell(m, diff([0; find(diff(m) > 2); numel(m)])), TES, 'UniformOutput', false);
TES_new = vertcat(splits{:})
  4 Comments
Guillaume
Guillaume on 3 Dec 2014
If I understood correctly, this is what you want:
TES={[1;2;3;4;5] 10;[12;13;14] 2;[1;2;3;4;8;9;10;22;23;24] 6;[4;5;6;8;9] 4;[5;6;7] 8} %for example
runlengths = cellfun(@(m) diff([0; find(diff(m) > 2); numel(m)]), TES(:, 1), 'UniformOutput', false);
splits = cellfun(@(m, runs) mat2cell(m, runs), TES(:, 1), runlengths, 'UniformOutput', false);
indices = cellfun(@(i, runs) repmat(i, numel(runs), 1), TES(:, 2), runlengths, 'UniformOutput', false);
TES_new = [vertcat(splits{:}) num2cell(vertcat(indices{:}))]

Sign in to comment.

More Answers (2)

Thorsten
Thorsten on 3 Dec 2014
This is somewhat similar to Star Strider's solution but with an extra index ind_new to get rid of the subarrays and with a copy of those arrays that need not to be split to the new cell:
TES={[1;2;3;4;5];[12;13;14];[1;2;3;4;8;9;10;22;23;24];[4;5;6;8;9];[5;6;7]};
i_new = 1;
for i=1:numel(TES)
split = find(diff(TES{i}) > 2);
if isempty(split)
TES_new{i_new} = TES{i};
i_new = i_new + 1;
else
ind = [0 split' numel(TES{i})];
for ii = 1:numel(ind2)-1
TES_new{i_new} = TES{i}(ind(ii)+1:ind(ii+1));
i_new = i_new + 1;
end
end
end
for i=1:numel(TES_new)
disp(TES_new{i})
end

Andrei Bobrov
Andrei Bobrov on 3 Dec 2014
n = cellfun(@numel,TES);
ii = accumarray(cumsum([1;n]),1);
ii = ii(1:end-1);
T = cat(1,TES{:})
jj = [1; abs(diff(T))>2];
out = accumarray(cumsum([jj | ii]),T,[],@(x){x})

Tags

Community Treasure Hunt

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

Start Hunting!