Справочник по динамическим полям для вложенных структур

В нашем коде MATLAB мы много использовали ссылки на динамические поля, и они довольно фантастические. У нас есть много разных структур данных с разными наборами полей, поэтому становится намного проще получить доступ к любой из них, просто используя нотацию struct.('field'), без использования оператора eval.

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

struct.('field.field2.field3')

Есть ли способ динамического доступа к структурам с неизвестной глубиной с помощью встроенных функций? Или нам нужно будет создать специальную функцию для доступа ко всем нашим структурам?

А вот с struct.('field.field2.field3') глубины нет? Или это struct.('unknown_amount_of_variables.desired_field')?

Ander Biguri 07.08.2018 15:01

Или вы ищете struct.('field').('field2').('field3')?

Ander Biguri 07.08.2018 15:03

@AnderBiguri это ближе всего к struct.('unknown_amount_of_variables.desired_field').

David K 07.08.2018 15:11

Вам нужно прочитать это, или написать, или и то, и другое? Могут ли они повторить? Может ли field3 находиться в разных местах в структуре?

Ander Biguri 07.08.2018 15:14

Пожалуйста, объясните, как вы получаете имена динамических полей.

Cris Luengo 07.08.2018 15:19

Облегчает ли решение этой проблемы знание того, что structB = structA.('fieldB'); не копирует никаких данных?

Cris Luengo 07.08.2018 15:21
«[Динамические имена полей] просто фантастические» - это довольно субъективно и, как правило, неверно с точки зрения производительности, читаемости кода, обслуживания или устойчивости ...
Wolfie 07.08.2018 15:31

@MohsenNosratinia Я не думаю, что это дубликат, поскольку OP упомянул, что они не знают переменных структуры. Просто где-то есть один с таким именем.

Ander Biguri 07.08.2018 15:55

@Wolfie, не могли бы вы рассказать о последствиях для производительности?

excaza 07.08.2018 16:18

@excaza У меня нет короткого теста для демонстрации, но часто в коде профилирования я видел, что индексирование с точечной нотацией может быть узким местом, особенно в отношении, например, индексации матрицы или массива ячеек. Сделав структуры данных как можно более плоскими, упростит доступ. Как только вам понадобятся вспомогательные функции для поиска полей для вас (при необходимости здесь), я могу только представить, что это станет во много раз более заметным! Не поймите меня неправильно, они часто могут сэкономить много работы по управлению рабочим пространством и ускорить кодирование, я просто отмечаю, что они не лучший метод де-факто.

Wolfie 07.08.2018 16:39

Я снова открыл вопрос, потому что то, что спросил OP, не в том, что находится в цели обмана.

Ander Biguri 07.08.2018 17:51

@AnderBiguri Я принял дубликат, потому что он, по сути, такой же, как то, что я собирался спросить. Я неправильно понял ваш первый комментарий для пояснения. Я знаю точное местоположение нужного поля, но только после того, как мне передадут строку с именами полей. Я не знаю, будет ли эта струна двухуровневой, пяти или двадцатой.

David K 07.08.2018 18:24

@DavidK, но тогда вы не можете использовать связанный дубликат, нет? потому что для этого вам нужны все поля.

Ander Biguri 07.08.2018 18:26

@AnderBiguri Мне передали строку, которая может быть field1.desiredField, field1.field2.desiredField или field1.<more levels>.desiredField. Я точно буду знать, где находится поле. Я пытался выяснить, есть ли встроенная функция, которая позволила бы мне получить доступ к этому полю динамически без использования eval или необходимости самостоятельно анализировать и зацикливать все.

David K 07.08.2018 18:35

ОК .... тогда закройте как дубликат.

Ander Biguri 07.08.2018 18:38

@DavidK Вы можете принять этот ответ как действительный, даже если вам понадобится что-то еще, для будущих читателей, у которых может быть проблема, которую вы описали

Ander Biguri 15.08.2018 16:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
16
96
1

Ответы 1

Этот код работает для следующих предположений и случаев использования:

  1. Есть поле, где вы не знаете, где оно находится внутри некоторой вложенной динамической структуры.
  2. Имя этого поля уникально, т.е. в структуре нет другого поля с таким же именем.

Работает следующая функция:

function [fieldplace]=findfield(s,field)

% is one of these?
fieldplace = {};
if (isfield(s,field))
    fieldplace{end+1}=field;
    return;
end

if ~isstruct(s)
    fieldplace = {};
    return;
end

% otherwise is nested somewhere, use recursivity.
fnames=fieldnames(s);
for ii=1:numel(fnames)
    fieldplace=findfield(s.(fnames{ii}),field);
    if ~isempty(fieldplace)
        fieldplace=[fnames{ii} fieldplace];
        return;
    end
end


end

Случай использования:

s.a=1;
s.b.c=2;
s.b.d=3;
s.e.f.g=4;
s.h.i.j.k=5;
result=findfield(s,'k');

Вы можете читать это поле как:

getfield(s,result{:})

Другие вопросы по теме