3

Lets say I have a structure like this:

S.index = 1:10;
S.testMatrix = zeros(3,3,10);
for x = 1:10
    S.testMatrix(:,:,x) = magic(3) + x;
end
S.other = reshape(0:39, 4, 10);

It contains a 1x10 vector, a 3x3x10 multi-paged array and a 4x10 matrix. Now say I want to select only the entries corresponding to the indices between 2 and 8. mask = S.index > 2 & S.index < 8;

I tried structfun(@(x) x(mask), S, 'UniformOutput', 0); first which correctly worked for only the vector, which makes perfect sense. So then I figured all I needed to do was expand my mask. So I did this.

test = structfun(@(x) x(repmat(mask, size(x, ndims(x) - 1), 1)), S, 'UniformOutput',0);

The expanded mask was correct for the matrix but not the multi-paged array. And the 2D matrix was flattened to a vector.

If I was going to index these elements individually I would do something like this:

S2.index = S.index(mask);
S2.other = S.other(:,mask);
S2.testMatrix = S.testMatrix(:,:,mask);

My use case is for hundreds of structures each with 20+ fields. How do I script the indexing? The exact problem occurs is limited to a structure with 1xN vectors, 3xN and 4xN matrices and 3x3xN arrays. The mask is constructed based on one of the vectors representing time. The field names are constant for each structure so I could brute force the thing and type in the commands and run it as a function, but I'm looking for an intelligent way to index it.

Update: Here is something that looks promising.

fn = fieldnames(S);
for x = 1:length(fn)
    extraDim = repmat({':'}, 1, ndims(S.(fn{x})) - 1);
    S2.(fn{x}) = S.(fn{x})(extraDim{:}, mask);
end

1 Answer 1

4

You can exploit the fact that the string ':' can be used as an index instead of :, and build a comma-separated list of that string repeated the appropriate number of times for each field:

s = {':',':'}; % auxilary cell array to generate the comma-separated list
S2 = structfun(@(f) f(s{1:ndims(f)-1}, mask), S, 'UniformOutput', false);
Sign up to request clarification or add additional context in comments.

1 Comment

@AnderBiguri Allowing that use of ':' makes indexing with chars a a little inconsistent, yes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.