Say I have some function that I'm applying every element in a list to... if that element matches some criteria:

If[#==<condition>,{#}, <Do nothing> ] & /@ LongList

Is there a way to do something like this? I want the result to just not have that element.

  • $\begingroup$ Welcome to Mathematica.SE, Andrew! I'm curious, how did you find this site? $\endgroup$ – Szabolcs Mar 24 '12 at 19:30
  • $\begingroup$ It's not clear to me why DeleteCases and similar functions are not the right tools for the job. Or you might perhaps prefer something like this: Flatten[If[# > 1, #, {Sequence[]}] & /@ {1, 2, 3, 0}] $\endgroup$ – Andrzej Kozlowski Mar 24 '12 at 19:30
  • $\begingroup$ I think this should be closed as a duplicate of this question but I don't want to cast a moderator super-vote. $\endgroup$ – Mr.Wizard Mar 24 '12 at 20:57
  • $\begingroup$ @Mr.Wizard I agree. I'm not voting because I've also answered it. $\endgroup$ – rm -rf Mar 24 '12 at 21:14
  • 1
    $\begingroup$ It is in substance but several of the answers to that question were specific to the implementation, testing for Image heads or Missing. Noone used DeleteCases. I think this question would be a better canonical version. $\endgroup$ – Verbeia Mar 24 '12 at 23:20

This specific behaviour can be achieved using

If[condition, something, Unevaluated@Sequence[]]& /@ list

The key is Sequence[]. Unevaluated prevents it from disappearing from inside the If.

Alternatively you can use Cases (or many other solutions shown in other answers and comments---some of these solutions may be better suited for the problem but Sequence[] has its place too).

Cases[list, element_ /; condition :> something]
| improve this answer | |
  • $\begingroup$ This is exactly what I was looking for. The Select answer I was aware of, but this is much more what I was looking for, I wasn't aware of the "Sequence[]" function. $\endgroup$ – Andrew Spott Mar 24 '12 at 23:39
  • $\begingroup$ @AndrewSpott Though I think this use of Sequence is OK here, this function has some peculiarities that you should be aware off, especially in combination with Part. Try, e.g., the following code s = {1, 2, 3} <ret> s[[1]] = Sequence[] <ret> s[[1]] <ret> s[[2]] <ret> s[[2]] = 1000 <ret> s[[2]] <ret> s <ret> and examine closely the output of the last two lines (every instruction should be on a separate line but that doesn't work here in comments). It will amaze you. $\endgroup$ – Sjoerd C. de Vries Mar 25 '12 at 20:50
  • $\begingroup$ Weird, is that a bug? Also, it seems to add some sort of history to the list, which would be ridiculously hard to debug, is there a way to remove that history? $\endgroup$ – Andrew Spott Mar 27 '12 at 18:10

In a similar vein to Szabolcs' first solution, you can use SlotSequence to achieve the same effect.

If[condition, <do something>, ## &[]] & /@ list
| improve this answer | |
  • 2
    $\begingroup$ ##&[] evaluates to Sequence[] as well. The difference is that ##&[] is not expanded in heads with HoldAll, while Sequence[] is (it needs HoldSequence to prevent that). $\endgroup$ – Szabolcs Mar 24 '12 at 23:24

You can combine Map (aka /@) and Select:

In[242]:= Sqrt /@ Select[{1, -2, 3, -4, 5}, # > 0 &]
Out[242]= {1, Sqrt[3], Sqrt[5]}

enter image description here

| improve this answer | |

In versions 11+, you can use Nothing for <do nothing>:

If[Mod[#, 3] == 0, #, Nothing] & /@ Range[20]

{3, 6, 9, 12, 15, 18}

| improve this answer | |

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.