Supongamos que tengo el siguiente struct en Matlab (leído de un archivo JSON):

>>fs.
fs.dichte              fs.hoehe               fs.ts2                 
fs.temperatur          fs.ts3                 fs.viskositaet
fs.ts1                 fs.ts4

Cada uno de los componentes fs.ts* contiene otro struct. En este caso particular, el índice de ts va de 1 a 4, pero en otro caso también podría ser 2 o 7. Entiendes la idea, ¿verdad? Quiero que el programa sea lo suficientemente flexible para manejar cualquier entrada posible. Entonces mi pregunta se reduce a: ¿Cómo consultar el índice máximo de ts? En un mundo ideal, esto funcionaría:

who fs.ts*

Pero desafortunadamente, simplemente no devuelve nada. ¿Algunas ideas?

( Por cierto, estoy usando Octave y no tengo Matlab disponible para probar; sin embargo, realmente debería haber una solución para esto que funcione en ambos entornos. )

2
rotton 29 ago. 2016 a las 15:07

2 respuestas

La mejor respuesta

Puede usar fieldnames para obtener todos los nombres de campo de la estructura, luego usar regexp para extraer los que comienzan con ts y extraer el número. Luego, puede comparar los números para encontrar el más grande.

fields = fieldnames(fs);

number = str2double(regexp(fields, '(?<=^ts)\d+$', 'once', 'match'));
numbers = number(~isnan(number));

[~, ind] = max(number);
max_field = fields{ind};
max_value = fs.(max_field);
3
Suever 29 ago. 2016 a las 13:42

No es una respuesta a su pregunta exacta, pero parece que en lugar de los campos tsN, debería tener un solo campo ts con una lista.

Consejo: cada vez que vea un número en un nombre de campo o variable, piense si no debería usar un vector / matriz / lista en su lugar.

Esto es cierto para todos los lenguajes, pero más para Octave, ya que todo son matrices. Incluso si tiene tres campos llamados ts1, ts2 y ts3 con valores escalares, lo que realmente tiene son tres campos cuyos valores son una matriz de tamaño 1x1.

En Octave puedes tener dos cosas. O el valor de ts es una matriz de celdas, cada elemento de la matriz de celdas es una estructura escalar; o es una matriz de estructura. Use una matriz de estructuras de celdas cuando cada estructura tenga claves diferentes, use una matriz de estructuras cuando todas las estructuras tengan las mismas claves.

Matriz de estructura

octave> fs.ts = struct ("foo", {1, 2, 3, 4}, "bar", {"a", "b", "c", "d"});
octave> fs.ts # all keys/fields in the ts struct array
ans =

  1x4 struct array containing the fields:

    foo
    bar

octave> fs.ts.foo # all foo values in the ts struct array
ans =  1
ans =  2
ans =  3
ans =  4

octave> numel (fs.ts) # number of structs in the ts struct array
ans =  4

octave> fs.ts(1) # struct 1 in the ts struct array
ans =

  scalar structure containing the fields:

    foo =  1
    bar = a

octave> fs.ts(1).foo # foo value of the struct 1
ans =  1

Matriz de celdas de estructuras escalares

Sin embargo, no estoy seguro de si JSON admite algo como matrices de estructuras, probablemente necesitará tener una lista de estructuras. En ese caso, terminará con una matriz de celdas de estructuras escalares.

octave> fs.ts = {struct("foo", 1, "bar", "a"), struct("foo", 2, "bar", "b"), struct("foo", 3, "bar", "c"), struct("foo", 4, "bar", "d"),};
octave> fs.ts # note, you actually have multiple structs
ans = 
{
  [1,1] =

    scalar structure containing the fields:

      foo =  1
      bar = a

  [1,2] =

    scalar structure containing the fields:

      foo =  2
      bar = b

  [1,3] =

    scalar structure containing the fields:

      foo =  3
      bar = c

  [1,4] =

    scalar structure containing the fields:

      foo =  4
      bar = d

}
octave-gui:28> fs.ts{1} # get struct 1
ans =

  scalar structure containing the fields:

    foo =  1
    bar = a

octave-gui:29> fs.ts{1}.foo # value foo from struct 1
ans =  1
2
carandraug 29 ago. 2016 a las 13:50