I'm looking for a way to split an input vector into groups of a predefined size, with the last group being smaller if there is a remainder. I prefer the output as a cell, but I don't mind if it's any other class as long as it provides access to the subgroups using subsequent indexing.
Below are examples of the expected behavior:
% Even split
v = 1:6;
grpSz = 2;
% OUT: {[1,2], [3,4], [5,6]}
% Remainder
v = 1:5;
grpSz = 3;
% OUT: {[1,2,3], [4,5]}
% Single group
v = 1:5;
grpSz = 6;
% OUT: {[1,2,3,4,5]}
Below are a couple of useful quantities:
nG = ceil(numel(v)/grpSz)
r = mod(numel(v), grpSz)
At the moment I'm using mat2cell
:
function out = evenSplitter(v, grpSz)
nV = numel(v);
nG = ceil(nV/grpSz);
r = mod(nV, grpSz);
out = mat2cell(v, 1, [repmat(grpSz, 1, nG-1), ~r*grpSz+r]);
...which works, but looks a bit clunky. Would anybody suggest a more elegant solution?
One solution using splitapply
:
v = 1:5; % input array
grpSz = 2; % maximal group size
out = splitapply(@(x){x},v,ceil((1:numel(v))/grpSz)) % split v
This method works for all the given examples.
splitapply
split data into groups and apply function. The anonymous function @(x){x}
simply put each element of a group into a cell. And ceil((1:numel(v))/grpSz)
create an array that indicate which elements are associated with which groups.
For example, if v = 1:5
and grpSz = 2
, ceil((1:numel(v))/grpSz)
produce the following array [1 1 2 2 3]
.