matlabvectorgroupingvectorizationmatrix-indexing

Splitting a vector into groups of a predefined size


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:


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?


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].