2
$\begingroup$

What is the difference between having Cases with selection condition presented by pattern and a with pure function as condition? What are the internal implementational reasons to have them separate?

As a side question: How can I select from a list of integers those that have a difference with their neighbor ( left or right, or both) unity?

$\endgroup$

marked as duplicate by MarcoB, Michael E2, Alexey Popkov, m_goldberg, Mr.Wizard Aug 9 '15 at 7:16

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • $\begingroup$ Can you give us an example of your first case? It's related to the second? $\endgroup$ – Murta Aug 9 '15 at 3:14
  • $\begingroup$ Regarding the side question also see: (23607) $\endgroup$ – Mr.Wizard Aug 9 '15 at 7:18
4
$\begingroup$

Any criteria (used for Select) can be written as the pattern _?(criteria) (used for Cases or DeleteCases). For single argument functions, the pure function can be abbreviated

list = Range[20];

Select[list, EvenQ[#] &] ==
 Select[list, EvenQ] ==
 Cases[list, _?(EvenQ[#] &)] ==
 Cases[list, _?EvenQ] ==
 DeleteCases[list, _?(! EvenQ[#] &)] ==
 DeleteCases[list, _?(OddQ[#] &)] ==
 DeleteCases[list, _?OddQ] ==
 Pick[list, EvenQ[list]] ==
 Range[2, 20, 2]

True

$\endgroup$
5
$\begingroup$

For the second part of question:

(n.b.: If you want positions instead of elements, change #[[Union[p - 1, p]]] to Union[p - 1, p].)

With[{p = Pick[Range@Length@#, Abs[Differences@Prepend[#, #[[1]] - 2]], 1]},
              #[[Union[p - 1, p]]]] &@theList

This will be much faster on larger lists then the solution based on Split from Alexey Popkov (which I up-voted - it's canonical and clean).

$\endgroup$
4
$\begingroup$

For your second question

How can I select from a list of integers those that have a difference with their neighbor ( left or right, or both) unity?

you could use:

lst = RandomInteger[10, 10]
Flatten@Select[Split[lst, Abs[#1 - #2] == 1 &], Length[#] > 1 &]
{8, 7, 5, 7, 0, 7, 6, 1, 1, 2}

{8, 7, 7, 6, 1, 2}
$\endgroup$
4
$\begingroup$

This is aimed at the first part of your question. I do not claim it is exhaustive.

Cases and Select behave differently in many situations.

Things Cases can do that Select can't

  • take a level specification
  • match and replace.
  • take an argument limiting the number of matches it returns

Cases and Select treat associations differently.

assoc = <|a -> 1, b -> 2|>;
assoc // Cases[_?(# > 1 &)]
{2}
assoc // Select[# > 1 &]
<|b -> 2|>
$\endgroup$
  • $\begingroup$ Actually already in Mathematica 5 Select accepts third argument limiting the number of matches it returns, so your third statement is incorrect. $\endgroup$ – Alexey Popkov Jun 14 '16 at 0:10

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