; $Id$ ;----------------------------------------------------------------------- ;+ ; NAME: ; CAT_STRUCT ; ; PURPOSE: Concatenate all tags within 2 or more structures. ; Return one structure with the same tags as each individual structure. ; ; CATEGORY: ; ; CALLING SEQUENCE: ; output = CAT_STRUCT( structure1, structure2, ... ) ; ; INPUTS: ; structure1, structure2,... - structures to be combined. ; ; KEYWORD PARAMETERS: ; ; OUTPUTS: ; output - a single structure containing all contents of the ; input structures. ; ; SUBROUTINES: ; ; REQUIREMENTS: ; ; NOTES: ; All input structures must have identical tag names. ; ; EXAMPLE: ; a = {Name: 'Larry', Age: 46} ; b = {Name: 'Chuck', Age: 10} ; c = {Name: 'Alice', Age: 35} ; ; d = cat_struct( a, b, c ) ; print, d.Name ; ; ; MODIFICATION HISTORY: ; cdh, 08 Jul 2010: VERSION 1.00 ; ;- ; Copyright (C) 2010, Christopher Holmes, UC Irvine ; This software is provided as is without any warranty whatsoever. ; It may be freely used, copied or distributed for non-commercial ; purposes. This copyright notice must be kept with any copy of ; this software. If this software shall be used commercially or ; sold as part of a larger package, please contact the author. ; Bugs and comments should be directed to cdholmes@post.harvard.edu ; with subject "IDL routine cat_struct" ;----------------------------------------------------------------------- function cat_struct, st1, st2, st3, st4, st5 ;; Note. The user can concatenate as many structures as desired by adding ;; extra input arguments: st6, st7, st8, etc ;; No further changes are required below to concatenate more structures. ;=============================================================== ; Setup and error checking ;=============================================================== ; Number of structures to concatenate = number of input arguments n_struct = n_params() ; Make sure that all input variables are structures and that ; all have the same number of tags FOR S=0L, n_struct-1L DO BEGIN ; Name of S^th input variable, as a string varnameS = 'st'+strtrim(string(S+1),2) ; Make sure it is a structure, otherwise error cmd = 'vartype = size(/type, '+varnameS+')' status = execute( cmd ) IF (vartype ne 8) THEN $ Message, 'Input argument '+varnameS+' is not a structure' IF (S eq 0) THEN BEGIN ; Get the tag names from 1st structure tagNames1 = tag_names( st1 ) ; Sort tag names in alphabetical order tagNames1 = tagNames1[ sort( tagNames1 ) ] ; Number of tags nTags1 = n_elements( tagNames1 ) ENDIF ELSE BEGIN ; Tag names for S^th structure cmd = 'tagNamesS = tag_names( '+varnameS+')' status = execute( cmd ) ; Sort tag names in alphabetical order tagNamesS = tagNamesS[ sort( tagNamesS ) ] ; Error if number of tags is not identical IF ( n_elements( tagNamesS ) ne nTags1 ) THEN $ Message, 'Tags in argument '+varnameS+' differ from argument 1' ; Error if names of tags differ FOR T=0L, nTags1-1L DO BEGIN IF ( tagNamesS[T] ne tagNames1[T] ) THEN $ Message, 'Tag names in argument '+varnameS+$ ' differ from argument 1' ENDFOR ENDELSE ENDFOR ;=============================================================== ; Construct a set of variables with the same names as the tags ; within each structure. The contents of the variables are the ; concatenated contents of the identical tags ;=============================================================== ; Get the number and names of tags from 1st structure tagNames = tag_names( st1 ) nTags = n_elements( tagNames ) FIRST = 1L ; Loop over the structures FOR S=0L, n_struct-1L DO BEGIN ; Name of S^th input variable varnameS = 'st' + strtrim( string( S+1 ), 2 ) IF (FIRST) THEN BEGIN FIRST = 0L ; Initialize variables with contents from 1st structure ; Put all tags into separate variables FOR T=0L, nTags-1L DO BEGIN cmd = tagNames[T] + ' = '+varnameS+'.'+tagNames[T] status = Execute( cmd ) ENDFOR ENDIF ELSE BEGIN ; For structures 2-end, concatenate each tag with the ; contents of the prior structures. FOR T=0L, n_elements(tagNames)-1L DO BEGIN cmd = tagNames[T] + ' = [ ' + tagNames[T] + ', '+ $ varnameS+'.'+tagNames[T] +' ]' status = Execute( cmd ) ENDFOR ENDELSE ENDFOR ;=============================================================== ; Create a new output structure which contains the concatenated ; data from the input structures. ;=============================================================== cmd = 'outStruct = {' ; Build a command that defines the output structure FOR T=0L, nTags-1L DO BEGIN IF (T eq 0L) THEN $ cmd = cmd + tagNames[T] +':'+ tagNames[T] $ ELSE $ cmd = cmd + ',' + tagNames[T] +':'+ tagNames[T] ENDFOR cmd = cmd + '}' ; Create the structure status= Execute( cmd ) ; Return concatenated structure return, outStruct END