Maximilian Ast
Maximilian Ast

Reputation: 3499

Group cell-array row by an ID in another row

I have got this cell-array:

QueueArr = ...
{   [1]    [5]    [1]    [2]    [1]    [ 1]    [ 5]    [ 1]    [ 2] ;  
    [6]    [8]    [7]    [9]    [5]    [10]    [18]    [17]    [19] }

Now I want to group the second row depending on the first one. My result cell-array should look like this:

loopCell = ...
{    [          1]    [          2]    [          5] ;
     [6 7 5 10 17]    [       9 19]    [       8 18] }

I solved this problem with this code:

%// convert from cell to a matrix
loopMatrix = cell2mat(QueueArr);
%// get the unique elements from the first row
loopMatrixUnique = unique(loopMatrix(1,:));
%// create the result cell
loopCell = cell(2,size(loopMatrixUnique,2));
%// iterate through the unique indexes
for i = 1:size(loopMatrixUnique,2)
    %// saving the first row
    loopCell{1,i} = loopMatrixUnique(i);
    %// calculating the grouped elements
    loopCell{2,i} = loopMatrix(2,loopMatrix(1,:) == loopMatrixUnique(i));
end

My question now is whether there is an easier or more ideal solution to my problem.

Upvotes: 0

Views: 105

Answers (2)

Maximilian Ast
Maximilian Ast

Reputation: 3499

I solved it myself with accumarray. thx to @Dan for the hint.

%// save the second row
sections = [QueueArr{2,:}];

%// get unique chapters and subs
[chapters, ~, subs] = unique([QueueArr{1,:}]);

%// create the grouped cell-array 
groups = accumarray(subs, sections, [], @(x) {x});

%// create the result cell-array
loopCell = [num2cell(chatpers); groups.'];

Upvotes: 1

Hoki
Hoki

Reputation: 11792

As you were told in comments, the 3rd output of unique is very usefull for your case.

Once you have that, cellfun can also be used to rebuild your cell array quickly:

b = cell2mat(QueueArr(2,:)) ; %// convert bottom line to array for convenience

[C,~,ic]= unique( cell2mat(QueueArr(1,:)) ) ;

R = [ num2cell(C) ; ...                                             %// top row
      cellfun( @(x) b(ic==x) , num2cell(1:length(C)) , 'uni',0)  ]  %// bottom row

Upvotes: 1

Related Questions