1

Given B = {"7" "8" "9"}, I'd like to use its values as respective replacements for the ultimate elements of each cell in A, i.e. transform

A = {{1 2} {3 4} {5 6}}

into

A = {{1 "7"} {3 "8"} {5 "9"}}

In unvectorized form, this can be written as:

nn = cellfun(@numel, A)
for i = 1:numel(a)
  A{i}{nn(i)} = B{i};
end

All sub-cells may have the same length, but a solution for sub-cells of arbitrary length would be ideal.

The only solution I found involves making a reshaped copy of A:

nn = cellfun(@numel, A)      #=> 2 2 2
A2 = horzcat(A{:})           #=> {1 2 3 4 5 6}
jj = cumsum(nn)              #=> 2 4 6
[A2{jj}] = B{:}              #=> {1 "7" 3 "8" 5 "9"}
ii = [1 jj(1:end-1)+1]       #=> 1 3 5
A = cellslices(A2,ii,jj,2)   #=> {{1 "7"} {3 "8"} {5 "9"}

I'd have hoped something like the below would work - but it doesn't:

octave:1> [[A{:}]{ii}] = B{:}
error: invalid lvalue function called in expression

Is there a way to vectorize this operation?

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313

1 Answers1

1

As learned from the comments that you actually just want to avoid an explicit for/while loop and are okay with cellfun (the use of which is not vectorisation), the process can be replicated with cellfun as follows:

A = cellfun(@(k) {A{k}{1:end-1} B{k}}, num2cell(1:numel(A)), 'un', 0);

or with arrayfun as:

 A = arrayfun(@(k) {A{k}{1:end-1} B{k}}, 1:numel(A), 'un', 0);
Sardar Usama
  • 19,536
  • 9
  • 36
  • 58