14
$\begingroup$

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.

$\endgroup$
8
  • $\begingroup$ Welcome to Mathematica.SE, Andrew! I'm curious, how did you find this site? $\endgroup$
    – Szabolcs
    Mar 24, 2012 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$ Mar 24, 2012 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, 2012 at 20:57
  • $\begingroup$ @Mr.Wizard I agree. I'm not voting because I've also answered it. $\endgroup$
    – rm -rf
    Mar 24, 2012 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, 2012 at 23:20

4 Answers 4

10
$\begingroup$

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]
$\endgroup$
3
  • $\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$ Mar 24, 2012 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$ Mar 25, 2012 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$ Mar 27, 2012 at 18:10
6
$\begingroup$

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

$\endgroup$
6
$\begingroup$

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

If[condition, <do something>, ## &[]] & /@ list
$\endgroup$
1
  • 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, 2012 at 23:24
4
$\begingroup$

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

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

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

$\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.