4
$\begingroup$

I have a nested association of the following form:

test = <|
"key1" -> <|"key11" -> 11, "key12" -> 12, "key13" -> 13|>,
"key2" -> <|0 -> <|"X" -> 5, "Y" -> 0|>, 1 -> <|"X" -> 6, "Y" -> 0|>,2 -> <|"X" -> 7, "Y" -> 0|>,3 -> <|"X" -> 8, "Y" -> 0|>|>,
"key3" -> <|"key31" -> 31, "key32" -> 32, "key33" -> 33|>
|>

"key2" refers to measurement points 0,1,2,3 each with an x- and y-value referable by "X" and "Y". Now I want to reduce the whole nested association test to a form, which only contains the measurement points with x>6. So the output should be:

test2 = <|
"key1" -> <|"key11" -> 11, "key12" -> 12, "key13" -> 13|>,
"key2" -> <|2 -> <|"X" -> 7, "Y" -> 0|>,3 -> <|"X" -> 8, "Y" -> 0|>|>,
"key3" -> <|"key31" -> 31, "key32" -> 32, "key33" -> 33|>
|>

Is there a convenient way to do so, that means without rebuilding the whole nested association? I tried alot using Delete, Select and Datset, but could not find any solution.

$\endgroup$
3
  • $\begingroup$ I guess you mean, you want to reduce it to key-value pairs that have X>6 or don't have X at all? $\endgroup$
    – Carl Lange
    May 22, 2021 at 14:47
  • $\begingroup$ No, I want to maintain the nested association with all points with x<=6 dropped from it. The aim is to achieve an output like test2 gives in my question. $\endgroup$
    – Sven
    May 22, 2021 at 15:05
  • 1
    $\begingroup$ MapAt[Cases[#, x_ /; x["X"] > 6, {1}] &, test, "key2"] ? $\endgroup$
    – Ben Izd
    May 22, 2021 at 15:28

2 Answers 2

3
$\begingroup$

If we can rely upon the target associations always being under "key2" and always having a subkey "X", then:

test // MapAt[Select[#X > 6 &], "key2"]

% === test2
(* True *)

or

test // Query[{"key2" -> Select[#X > 6 &]}]

In a more general case where we do not know the parent key or even if the subvalues are necessarily associations, then:

DeleteCases[test, KeyValuePattern[{"X" -> x_ /; x <= 6}], {2}]

If we know neither the parent key nor even the level of the target associations, then::

DeleteCases[test, KeyValuePattern[{"X" -> x_ /; x <= 6}], Infinity]
$\endgroup$
1
  • $\begingroup$ Great, thank you very much! Very elegant solutions. $\endgroup$
    – Sven
    May 23, 2021 at 12:35
4
$\begingroup$
test = <|"key1" -> <|"key11" -> 11, "key12" -> 12, "key13" -> 13|>, 
   "key2" -> <|0 -> <|"X" -> 5, "Y" -> 0|>, 1 -> <|"X" -> 6, "Y" -> 0|>,
      2 -> <|"X" -> 7, "Y" -> 0|>, 3 -> <|"X" -> 8, "Y" -> 0|>|>, 
   "key3" -> <|"key31" -> 31, "key32" -> 32, "key33" -> 33|>|>;
keepkeys2 = Position[test["key2"], x_ /; x["X"] > 6]
keepvals2 = Extract[test["key2"], keepkeys2]
new2 = AssociationThread[Flatten@keepkeys2, keepvals2]
ReplacePart[test, "key2" -> new2]
$\endgroup$
3
  • $\begingroup$ Great! Small error. First keepkeys should not be keepkeys2 $\endgroup$
    – FredrikD
    May 22, 2021 at 16:50
  • $\begingroup$ @FredrikD Fixed. $\endgroup$
    – Alan
    May 22, 2021 at 17:24
  • $\begingroup$ Thanks for your solution. Works fine! $\endgroup$
    – Sven
    May 23, 2021 at 12:33

Your Answer

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

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