6
$\begingroup$

I was wondering whether there is a stronger Nothing or whether this can easily be constructed. By stronger I mean the following:

If we have Table[Nothing,{i,1,3}] it will return {}. If we write Table[Nothing,{i,1,3},{j,1,3}] it will return {{},{},{}}. The Nothing cannot delete these lists since it is no longer there. Often I do want a list like this to collapse to {}. Practically, there is a very easy solution to retrieve the output I wish (such as {}->Nothing), but mostly I'm just curious for a solution of this type.

The new nothing would differ from Nothing in that {nothing} -> nothing if {nothing} is an element of a list (instead of to {}).

P.S. To clarify the objective: the new nothing would be applied to get nice lists without empty lists for objects like Table[If[cnd[i],x[i],nothing,nothing],{i,1,n},{j,1,m}].


I am close to an answer with

nothing /: List[nothing] := nothing;
nothing /: List[a__, nothing] := List[a];
nothing /: List[nothing, b__] := List[b];

which I think is acceptable for me. However, it gets the wrong result for the outer list {nothing}->nothing if the whole thing turns out filled with nothing but nothing's.

How do I define an object so that it has a different definition depending on whether it is contained in a list or not?

$\endgroup$
  • $\begingroup$ I don't think there's anything really built in, but a small tweak to your stuff will do it: nothing /: List[a__, nothing, b___] := List[a, b]; nothing /: List[a___, nothing, b__] := List[a, b];. Note the addition of triple underscores. That's actually important. By the way, you'll want to wrap those up-values in HoldPattern for if you want to tweak at all. $\endgroup$ – b3m2a1 Mar 17 '17 at 16:52
  • $\begingroup$ @MB1965 Nice. Yes of course, great with the double underscores on one side and triple on the other so that "nothing" always vanishes if paired with something else, otherwise it would get stuck in the middle. How exactly do I use HoldPattern (if you have the time, otherwise I will find out on my own)? I take it the purpose would be to avoid evaluating the upvalues on the left hand side of definitions. $\endgroup$ – Kvothe Mar 17 '17 at 17:31
  • $\begingroup$ use it around the entire pattern, e.g. nothing /: HoldPattern[List[a___, nothing, b__]] := List[a, b];. Prevents List[a___, nothing, b__] from evaluating to List[a___, b__] but matches List[a___, nothing, b__]. If you check the *Values for a function you'll see this is how they're stored. $\endgroup$ – b3m2a1 Mar 17 '17 at 17:59
5
$\begingroup$

One way is to specify explicitly how many levels of empty Lists you wish to remove, for example:

ClearAll[nothing]
nothing /: List[nothing[0] ..] := {};
nothing /: List[nothing[i_Integer] ..] := nothing[i - 1];
nothing /: List[a___, nothing[i_Integer], b___] := List[a, b];

Now

Table[nothing[0], {i, 1, 3}]
Table[If[EvenQ[i], i, nothing[0]], {i, 1, 5}]
Table[nothing[1], {i, 1, 3}, {j, 1, 3}]
Table[If[EvenQ[i], i, nothing[1]], {i, 1, 3}, {j, 1, 3}]
Table[nothing[2], {i, 1, 3}, {j, 1, 3}, {k, 1, 3}]
Table[If[EvenQ[i], i, nothing[2]], {i, 1, 3}, {j, 1, 3}, {k, 1, 3}]
{}

{2, 4}

{}

{{2, 2, 2}}

{}

{{{2, 2, 2}, {2, 2, 2}, {2, 2, 2}}}

In the above nothing[0] is an equivalent of Nothing (doesn't remove {}), nothing[1] removes only {}, nothing[2] removes also {{}} etc.


If the goal is just to get nice-looking output, then solution is very simple:

ClearAll[nothing]
Format[nothing] = {};
nothing /: List[nothing ..] := nothing;
nothing /: List[a___, nothing, b___] := List[a, b];

Now

Table[nothing, {i, 1, 3}]
Table[If[EvenQ[i], i, nothing], {i, 1, 5}]
Table[nothing, {i, 1, 3}, {j, 1, 3}]
Table[If[EvenQ[i], i, nothing], {i, 1, 3}, {j, 1, 3}]
Table[nothing, {i, 1, 3}, {j, 1, 3}, {k, 1, 3}]
Table[If[EvenQ[i], i, nothing], {i, 1, 3}, {j, 1, 3}, {k, 1, 3}]
{}

{2, 4}

{}

{{2, 2, 2}}

{}

{{{2, 2, 2}, {2, 2, 2}, {2, 2, 2}}}

Note however that it is just how the output is formatted for displaying in the FrontEnd, in the Kernel we have another expression:

out = Table[nothing, {i, 1, 3}]
FullForm[out]
{}

nothing

Also it will collapse enclosing Lists as well:

{Table[nothing, {i, 1, 3}]}
{{Table[nothing, {i, 1, 3}]}}
{}

{}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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