5

Given the following MWE, where:

lst = {<|"a" -> 1, "b" -> 2|>,
   <|"a" -> 2, "b" -> 2|>,
   <|"a" -> 3, "b" -> 2|>,
   <|"a" -> 4, "b" -> 2|>,
   <|"a" -> 5, "b" -> 2|>};

and the problem is that:

if the value of a is greater than 3 then "c"-> True must be added to the association.

I have the following =working= code

Map[If[#[[1]] > 3, var = #; AssociateTo[var, "c" -> True], #] &, lst]

which yields:

{<|"a" -> 1, "b" -> 2|>, 
<|"a" -> 2, "b" -> 2|>, 
<|"a" -> 3, "b" -> 2|>, 
<|"a" -> 4, "b" -> 2, "c" -> True|>, 
<|"a" -> 5, "b" -> 2, "c" -> True|>}

I prefer If-less programming and the var=# looks so unnecessary.

Is there a more "elegant" solution to this problem?

nilo de roock
  • 9,657
  • 3
  • 35
  • 77

3 Answers3

10

# and If -less approach:

lst /. a : KeyValuePattern["a" -> n_ /; n > 3] :> <|a, "c" -> True|>
Kuba
  • 136,707
  • 13
  • 279
  • 740
7

Terse style:

<|#, If[#a > 3, "c" -> True, {}]|> & /@ lst
{
 <|"a" -> 1, "b" -> 2|>,
 <|"a" -> 2, "b" -> 2|>,
 <|"a" -> 3, "b" -> 2|>,
 <|"a" -> 4, "b" -> 2, "c" -> True|>,
 <|"a" -> 5, "b" -> 2, "c" -> True|>
}

For what it's worth version 10.1 does not have KeyValuePattern, but this works:

lst /. x_ /; x["a"] > 3 :> <|x, "c" -> True|>

And just to play with other methods:

<|#, DeleteCases[<|"c" -> #a > 3|>, False]|> & /@ lst
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
6

I recommend

If[#a > 3, Append[#, "c" -> True], #] & /@ lst

if you can tolerate a bit of If.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263