Численное повторение структуры MATLAB

Можно ли перебирать структуру MATLAB численно, как вектор, вместо использования имен полей?

Просто я пытаюсь сделать следующее внутри блока EML для Simulink:

S.a.type = 1;
S.a.val = 100;
S.a.somevar = 123;    
S.b.type = 2;
S.b.val = 200;
S.b.somevar2 = 234;
S.c.type = 3;
S.c.val = 300;
S.c.somevar3 = 345;

for i = 1:length(s)
    itemType = S(i).type;
    switch itemType
        case 1
            val = S(i).val * S(i).somevar1;
        case 2
            val = S(i).val * S(i).somevar2;
        case 3
            val = S(i).val * S(i).somevar3;
        otherwise
            val = 0
    end
end

disp(var);

person tmar89    schedule 21.09.2011    source источник
comment
См. этот вопрос Как мне получить доступ к полям структуры MATLAB в пределах петля?   -  person Aabaz    schedule 21.09.2011


Ответы (2)


Вам нужно использовать имена полей, но вы можете сделать это динамически. Если у вас есть структура, определенная как:

s.field1 = 'foo';
s.field2 = 'bar';

Затем вы можете получить доступ к полю field1 с помощью

s.field1
s.('field1')

Единственное, что вам нужно, это функция fieldnames для динамического получения имен полей, чтобы ваш пример кода выглядел примерно так:

elements = fieldnames(S);
for iElement = 1:numel(elements)
   element = S.(elements{iElement});
   itemType = element.type;
   switch itemType
      case 1
          val = element.val * element.somevar1;
      case 2
          val = element.val * element.somevar2;
      case 3
          val = element.val * element.somevar3;

   end
end

Если это точные имена полей, вы должны сделать некоторые другие вещи. Во-первых, вам нужно будет переосмыслить свои имена, а во-вторых, вы можете использовать часть решения Мэтта для упрощения своего кода.

person Egon    schedule 21.09.2011
comment
Это в основном то, что у меня есть, но проблема в том, что функциональные блоки Matlab Embedded в Simulink не поддерживают этот метод. Во-первых, для имен полей требуется coder.instrinsic, а затем операции с ячейками не поддерживаются. Я также пытался сделать что-то немного другое, когда я просто увеличивал имена полей, как вы, s.field1, s.field2, и в коде пытался увеличивать, например: s.(['field' i]), но это тоже не работает. Облом! - person tmar89; 23.09.2011
comment
@tmar89: о, понятно. У меня не так много опыта работы с SimuLink и кодировщиком, чтобы знать, что поддерживается, а что нет, но я полагаю, что если мое решение не работает, это может быть что-то фундаментальное, чего не хватает при генерации кода. - person Egon; 24.09.2011

Вы должны иметь возможность динамически генерировать имена полей с помощью sprintf, используя что-то вроде следующего:

for i = 1:length(s)
    theFieldName = sprintf('somevar%d', S(i).type);
    val = S(i).val * getfield(S(i), theFieldName);
end
person Matt    schedule 21.09.2011