Differentiating between zero and "empty" in lists, and adding them?
This works, though it's not as terse as I would have hoped.
list1 = {-2, e, e, 0, e, -1, e}
list2 = {-1, e, 0, e, e, 1, 5}
I use e
because E
is a built in symbol.
Replace[Thread[{list1, list2}], {{e ..} :> e, {x__} :> Total[{x} /. e :> 0]}, {1}]
{-3, e, 0, 0, e, 0, 5}
Initially I tried
e + x_ ^:= x
But when we have e + 0
, this evaluates to just e
before the UpValues
rule has a chance to turn this into 0
.
Per suggestion of @J.M., we can use CirclePlus
(or the infix form ⊕
which is typed by sequentially pressing Esc+C+++Esc) to make an addition function that follows your definitions.
SetAttributes[CirclePlus, {Flat, Orderless, OneIdentity, Listable}]
e /: e⊕x_ := x
(a : Except[e])⊕(b : Except[e]) := a + b
Then
list1 ⊕ list2 -> {-3, e, 0, 0, e, 0, 5}
It is also possible to use TagSetDelayed
to make the built-in Plus
to behave like you want, but only if you abandon using the integer 0
and use the floating point 0.
instead.
list1 = N@list1
list2 = N@list2
e /: e + 0. := 0.
e /: e + e := e
list1 + list2
{-3., e, 0., 0., e, 0., 5.}
Perhaps the most simple and elegant solution to this is to let all of your numbers be real and use the integer zero for "empty". Then the built in Plus
does just what you want:
{-2., 0, 0, 0., 0, -1., 0} + {-1., 0, 0., 0, 0, 1., 5.}
{-3., 0, 0., 0., 0, 0., 5.}
convert for display:
% /. {0 -> e , x_Real :> Round[x]}
{-3, e, 0, 0, e, 0, 5}