1
$\begingroup$

I am importing different associations and wanting to merge them. An example of these associations are:

 TempAss1=<|1.1 -> <|9.5 -> <|0.432 -> <|-45. -> {A -> -369075., 
             Tau -> 1.87819*10^6, \[Eta] -> 1584.57, Const -> 369299.}, 
           45. -> 0|>, -1.3 -> <|-45. -> 0, 45. -> 0|>, 
         0.518 -> <|-45. -> 0, 45. -> 0|>|>, 
       0.3 -> <|0.432 -> <|-45. -> 0, 
           45. -> 0|>, -1.3 -> <|-45. -> {A -> -390.486, 
             Tau -> 23684.5, \[Eta] -> 20.5309, Const -> 612.14}, 
           45. -> 0|>, 0.518 -> <|-45. -> 0, 45. -> 0|>|>, 
       95. -> <|0.432 -> <|-45. -> 0, 
           45. -> 0|>, -1.3 -> <|-45. -> {A -> -45.7498, 
             Tau -> 240.096, \[Eta] -> 0.63088, Const -> 237.389}, 
           45. -> 0|>, 
         0.518 -> <|-45. -> {A -> -44.387, 
             Tau -> 258.905, \[Eta] -> 5.09056, Const -> 236.875}, 
           45. -> 0|>|>|>|>

    TempAss2=<|1.1 -> <|0.3 -> <|0.518 -> <|-45. -> {A -> -33.1905, 
         Tau -> 1.61068, \[Eta] -> 0.5, Const -> 238.764}, 
       45. -> {A -> 22.148, Tau -> 23.5145, \[Eta] -> 0.5, 
         Const -> 245.623}|>, 
     0.432 -> <|-45. -> 0, 
       45. -> {A -> 22.6187, Tau -> 1.26661, \[Eta] -> 0.903167, 
         Const -> 244.298}|>, -1.3 -> <|-45. -> 0, 
       45. -> {A -> 19.5818, Tau -> 59.0678, \[Eta] -> 0.5, 
         Const -> 248.05}|>|>, 
   9.5 -> <|0.518 -> <|-45. -> 0, 45. -> 0|>, 
     0.432 -> <|-45. -> 0, 
       45. -> {A -> 40.9493, Tau -> 2.53002, \[Eta] -> 0.918688, 
         Const -> 244.598}|>, -1.3 -> <|-45. -> 0, 45. -> 0|>|>, 
   95. -> <|0.518 -> <|-45. -> 0, 
       45. -> {A -> 40.4232, Tau -> 120.088, \[Eta] -> 0.56459, 
         Const -> 249.343}|>, 
     0.432 -> <|-45. -> 0, 45. -> 0|>, -1.3 -> <|-45. -> 0, 
       45. -> {A -> 26.7719, Tau -> 7.67733, \[Eta] -> 0.912373, 
         Const -> 264.38}|>|>|>|>

They might have slight deviations in the keys (both names and positions) in each associations, but the format will be same i.e. they will have the same order of keys if matching, and the same depth. If the key isn't shared between the two, it can be added (which can be done) but if there is the same key I would want it to be updated with the new value, unless it is a zero. Union works to update them, but if the value is 0 it would replace a value. I wouldn't mind the updating of a new value in the same key (as to not get a list as would occur with Merge[...Identity]).

An option would be delete the zero values from each association before merging, but with these nested associations I am not sure how to do this.

EDIT: I can delete the zero values using:

tst = DeleteCases[TempAss1, 0, {-1}];
tst = DeleteCases[tst, <||>, {-2}]

Which removes the 0 values and any keys associated with that value (if then deleted).

Any help would be appreciated.

$\endgroup$

3 Answers 3

2
$\begingroup$

If I understand correctly your problem comes about due to the nested structure of your associations, otherwise you'd just be using Merge. You can overcome this issue with recursion (let me know if the following requires further explanation):

ClearAll@RecursiveMerge;
RecursiveMerge[l : {__Association}] := Merge[l, RecursiveMerge]
RecursiveMerge[l_] := First@Append[DeleteCases[l, 0], empty]

RecursiveMerge[{TempAss1, TempAss2}]
(*<|1.1 -> <|9.5 -> <|0.432 -> <|-45. -> {A -> -369075., 
         Tau -> 1.87819*10^6, \[Eta] -> 1584.57, Const -> 369299.}, 
       45. -> {A -> 40.9493, Tau -> 2.53002, \[Eta] -> 0.918688, 
         Const -> 244.598}|>, -1.3 -> <|-45. -> empty, 45. -> empty|>,
      0.518 -> <|-45. -> empty, 45. -> empty|>|>, 
   0.3 -> <|0.432 -> <|-45. -> empty, 
       45. -> {A -> 22.6187, Tau -> 1.26661, \[Eta] -> 0.903167, 
         Const -> 244.298}|>, -1.3 -> <|-45. -> {A -> -390.486, 
         Tau -> 23684.5, \[Eta] -> 20.5309, Const -> 612.14}, 
       45. -> {A -> 19.5818, Tau -> 59.0678, \[Eta] -> 0.5, 
         Const -> 248.05}|>, 
     0.518 -> <|-45. -> {A -> -33.1905, Tau -> 1.61068, \[Eta] -> 0.5,
          Const -> 238.764}, 
       45. -> {A -> 22.148, Tau -> 23.5145, \[Eta] -> 0.5, 
         Const -> 245.623}|>|>, 
   95. -> <|0.432 -> <|-45. -> empty, 
       45. -> empty|>, -1.3 -> <|-45. -> {A -> -45.7498, 
         Tau -> 240.096, \[Eta] -> 0.63088, Const -> 237.389}, 
       45. -> {A -> 26.7719, Tau -> 7.67733, \[Eta] -> 0.912373, 
         Const -> 264.38}|>, 
     0.518 -> <|-45. -> {A -> -44.387, 
         Tau -> 258.905, \[Eta] -> 5.09056, Const -> 236.875}, 
       45. -> {A -> 40.4232, Tau -> 120.088, \[Eta] -> 0.56459, 
         Const -> 249.343}|>|>|>|>*)

NOTE: I've added the empty symbol as a flag to mark entries where all the values being merged are 0's, because it's unclear from your description what you're supposed to do then... but this behavior can easily be changed.

$\endgroup$
1
  • $\begingroup$ Absolutely great! Works a treat! The case where both are zero wouldn't come up now that I have added a section that deletes those zero values, but having a flag there just in case is useful $\endgroup$
    – Xyive
    Jun 3, 2021 at 17:08
1
$\begingroup$

Essentially, we need Merge in this case.

And, the ResourceFunctions, AssociationKeyFlatten and AssociationKeyDeflatten, may make our lives easier:

Merge[ResourceFunction["AssociationKeyFlatten"] /@ {TempAss1, 
    TempAss2}, Flatten] // ResourceFunction["AssociationKeyDeflatten"]
$\endgroup$
0
$\begingroup$

Using the Delete cases used in the edit I used:

assocList = KeyUnion[{TempAss1, TempAss2}];
MergedAssociation = Merge[{assocList[[2]], assocList[[1]]},Merge[Merge[Merge[Flatten]]]] 

The KeyUnion came from Caitlin J. Ramsey in link. The multiple Merge commands were needed to get to the correct depth into the association. I used flatten, which keeps all the values (both new and old) but as assocList[[2]] is before assocList[[1]], the newer values will appear first in the flattened list. This means any code that is based from this can be 'told' to only select the first batch of values, without having to reorganise/undo a list.

Make sure if you are using this, and looping it, that for the first iteration the associations in the KeyUnion aren't empty, as this will error. Just set MergedAssociation as the TempAss used in the first iteration.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.