Array di Struct: ottengo 1struct invece che 1array di struct

di il
5 risposte

Array di Struct: ottengo 1struct invece che 1array di struct

Ciao, ho un array di structs che contengono stringhe e lo voglio trasformare in un array di structs contenente valori in formato numerico. Il codice che ho creato funziona ma invece che memorizzare i valori relativi a tutte le struct, memorizza solo quelli relativi all'ultima...
for i=1:size(s,2)
% gestisce la presenza di struct vuote
if(isempty(s(1,i).locs))
continue
%gestisce l'assenza dei valori di inizio/fine rilevazione
elseif(isempty(s(1,i).places))
continue
else
date=datevec(s(1,i).locs(:,1));
% Data di inizio rilevazione
dateStart=datevec(s(1,i).places.startdate(:,1));
% Data fine rilevazione
dateEnd=datevec(s(1,i).places.endate(:,1));
end
end

non riesco a trovare l'errore... dovrei pre-allocare date, dateStart e dateEnd?

5 Risposte

  • Re: Array di Struct: ottengo 1struct invece che 1array di struct

    Se, all'interno di un loop, assegni un valore ad una variabile scalare come nel codice che hai riportato:
    date=datevec(s(1,i).locs(:,1));
    dateStart=datevec(s(1,i).places.startdate(:,1));
    dateEnd=datevec(s(1,i).places.endate(:,1));
    
    il valore assegnato ad ogni iterazione sostituirà quello assegnato nell'iterazione precedente; questo comporta che, al termine del loop la variabile scalare conterrà il valore assegnato nel corso dell'ultima iterazione (che è quanto appunto accade a te).

    Devi, quindi, trasformare le variabili attualmente "scalari" in vettori:
    date(i)=datevec(s(1,i).locs(:,1));
    dateStart(i)=datevec(s(1,i).places.startdate(:,1));
    dateEnd(i)=datevec(s(1,i).places.endate(:,1));
    
    dal momento che nel codice hai identificato la possibilità che ci siano casi nei quali l'assegnazione non viene effettuata (vedi i casi nei quali gestisci l'assenza di dati all'interno della struttura) devi anche valutare se utilizzare come indice dei vettori "date", "dateStart" e "dataEnd" l'indice "i" del loop o un contatore che venga incrementato solo in presenza di valori (il contatore va inizializzato prima del loop ed incrementato dopo l'assegnazione dell'opportuno valore al vettore "dateEnd" (ultima isgtruzione del loop).

    Nel primo caso i vettori "date", "dateStart" e "dataEnd" avranno delle locazioni "vuote" in corrispondenza degli indici "i" per i quali non sono presenti valori nei campi della struttura.

    Nel secondo caso i vettori non avranno locazioni vuote, ma "perderai" la corrispondenza biunivoca (a livello di "posizione" all'interno dei vettori) tra gli elementi dei campi della struttura e quelli dei vettori "date", "dateStart" e "dataEnd".

    Hope this helps.
  • Re: Array di Struct: ottengo 1struct invece che 1array di struct

    Grazie mille, ho parzialmente risolto il problema modificando il codice come segue

    nCols = size(s,2);
    dateAll = zeros(nCols,6);
    dateBeg = zeros(nCols,6);
    dateEnd = zeros(nCols,6);
    for k = 1:nCols
    if ~isempty(s(1,k).locs)
    dateAll(k,:) = datevec(s(1,k).locs(:,1))
    end
    if ~isempty(s(1,k).places)
    dateBeg(k,:) = datevec(s(1,k).places.startdate(:,1));
    dateEnd(k,:) = datevec(s(1,k).places.endate(:,1));
    end
    end

    ho un errore su dateAll che sto cercando di risolvere: mi da errore in quanto dateAll non ha dimensione pari a nCols ma dovrebbe essere un array di 106 struct con dimensioni variabili in base al valore di s.locs.
    suggerimenti sono ben accetti
  • Re: Array di Struct: ottengo 1struct invece che 1array di struct

    Non disponendo dei dati di input (quelli contenuti nella struttura "s" e le dimensioni dei suoi campi) è difficile dare ulteriori suggerimenti.

    Sarebbe intanto utile conoscere l'esatto messaggi di errore che viene generato.

    Alcune considerazioni / domande / punti da verificare:
    nCols = size(s,2);
    dateAll = zeros(nCols,6);
    
    in nCols hai il numero di colonne della matrice di strutture "s" però, poi, utilizzi questo valore come numero di righe per l'inizializzazione della matrice "allDate": sei sicura che sia giusto?

    Nel loop consideri sempre solo la prima riga della matrice "s": è giusto?

    Che tipo di variabile è "locs"? E' una matrice? Una strutture? un cellarray?

    Cosa contiene "locs"?

    Dovresti analizzare con il debugger il contenuto di "datevec(s(1,k).locs(:,1))": cosa contiene?
    E' compatibile con la definizione della matrice "allDate"?

    Per il momento l'unico suggerimento che posso darti è quello di analizzare il contenuto dei vari campi della struttura "s" ed il modo con il quale accedi ad essi all'interno del loop: con l'istruzione datevec(s(1,k).locs(:,1)) passi in input alla funzione "datevec" a tutte le righe della prima colonna di "loc": cosa è contenuto in tutte le righe della prima colonna di "loc"? A senso passare tutte queste informazioni a "datevec"?

    Ricorda, il debugger è il tuo migliore amico!

    Hope this helps.
  • Re: Array di Struct: ottengo 1struct invece che 1array di struct

    Grazie dei suggerimenti... ieri sera ho modificato ulteriormente il codice e con il debug ho capito il problema ma non so come risolverlo

    % nCols: dimensione dell'array di struct colonne 106
    nCols = size(s,2);

    % Pre-allocazione delle matrici dateBeg e dateEnd che conterranno
    % rispettivamente le date di inizio e di termine della rilevazione
    dateBeg = zeros(nCols,6);
    dateEnd = zeros(nCols,6);
    % dateAll=[];

    % Per k che va da 1 a 106, se i campi s.locs dell'array di struct sono non
    % nulli, metto i dati in dateAll
    for k = 1:nCols
    if ~isempty(s(1,k).locs)
    str = s(1,k).locs(:,1);
    tmp = datevec(str);
    dateAll(k,:) = tmp;
    end

    % se i campi s.places non sono vuoti per le struct dell'array, metto i
    % valori di startdate e endate rispettivamente in dateBeg e dateEnd
    if ~isempty(s(1,k).places)
    dateBeg(k,:) = datevec(s(1,k).places.startdate(:,1));
    dateEnd(k,:) = datevec(s(1,k).places.endate(:,1));

    end
    end

    debugando il primo if, ho notato che tutto funziona tranne la riga dateAll(k,:) = tmp, matlab mi da il seguente errore che non so come risolvere.

    Subscripted assignment dimension mismatch.

    Error in ProvaArrayStruct (line 16)
    dateAll(k,:) = tmp;

    Ho capito che c'è un errore dimensionale ma non so come poterlo risolvere

    s è un array di strutture, s.locs è una matrice di double che ha dimensione variabile in base alla struttura dati. Se avete qualche suggerimento sarebbe gradito.
  • Re: Array di Struct: ottengo 1struct invece che 1array di struct

    Con riferimento al codice che hai inserito:
    s.locs è una matrice di double che ha dimensione variabile
    str = s(1,k).locs(:,1);
    tmp = datevec(str);
    str sarà un vettore colonna, supponiamo di 3 elementi

    "tmp" sarà una matrice (3 x 6)

    L'errore si verifica nell'istruzione
    dateAll(k,:) = tmp;
    perchè vuoi assegnare una matrice (3 x 6) ad una riga di una matrice.

    Per eliminare l'errore, le matrici "dateAll", dateBeg" e "dateEnd" devono essere definite come matrici a 3 dimensioni come nell'esempio che segue.
    % Generazione della struttura di eempio
    s(1).locs=[725000.0 725000.3;
       725001.0 725002.9;
       725030.0 725004.1]
    s(2).locs=[725030.0 735000.3;
       726001.0 725003.9;
    %   732145.8 800000.1
       727030.0 725704.1]
    % Identificazione del numero di colonne della struttura
    nCols=size(s,2)
    % Loop sugli elemenrti della matrice di strutture
    for i=1:nCols
       dateAll(:,:,i)=datevec(s(i).locs(:,1))
    end
    
    Questo approccio funziona se i campi "locs" dei vari elementi di"s" hanno tutti lo stesso numero di righe (prova a "scommentare" la riga commentata nella definizione di "s(2).loc").

    Per una soluzione più generale che funzioni anche nel caso il numero di righe delle matrici "locs" non sia lo stesso per ogni elemento della struttura "s", puoi usare dei "cellarray" al posto delle matrici "dateAll", dateBeg" e "dateEnd" come nell'esempio che segue:
    % Generazione della struttura di eempio
    s(1).locs=[725000.0 725000.3;
       725001.0 725002.9;
       725030.0 725004.1]
    s(2).locs=[725030.0 735000.3;
       726001.0 725003.9;
      732145.8 800000.1
       727030.0 725704.1]
    % Identificazione del numero di colonne della struttura
    nCols=size(s,2)
    % Loop sugli elemenrti della matrice di strutture
    for i=1:nCols
    %    dateAll(:,:,i)=datevec(s(i).locs(:,1))
       dateAll{i}=datevec(s(i).locs(:,1))
    end
    
    Per accedere direttamente alle matrici allocate in ogni elemento del cellarray:
    m=[dateAll{i}]
    dove "i" è l'i-esimo elemento del cellarray.

    Hope this helps.
Devi accedere o registrarti per scrivere nel forum
5 risposte