6
$\begingroup$

I am trying to avoid using For because I heard that For is not cool in functional programming. Below is a problem that the first idea came to my mind is using For. How can I change this into a code using Table or Range or something else?

What the code does is to extract the elements in a list ls which satisfies certain condition into a new list lsNew.

ls = RandomInteger[20, 1000];
lsNew = {};
For[i = 1, i <= Length[ls], i++,
  If[ls[[i]] < 6, lsNew = Append[lsNew, ls[[i]]]]]
lsNew
$\endgroup$
2
  • $\begingroup$ Use Select instead. The setup is much, much simpler, and it doesn't use $O(n^2)$ methods to do it. (Append used like this is the culprit.) $\endgroup$
    – rcollyer
    Dec 29, 2015 at 3:38
  • $\begingroup$ Related: mathematica.stackexchange.com/a/2822/1871 $\endgroup$
    – xzczd
    Dec 29, 2015 at 3:41

3 Answers 3

10
$\begingroup$

Have a look at Select.

lsNew = Select[# < 6 &]@ls
$\endgroup$
2
  • 3
    $\begingroup$ As from 10.3 we can also use LessThan[6] instead of the pure function. $\endgroup$ Dec 29, 2015 at 12:58
  • $\begingroup$ @SimonWoods Ah, the operator forms of inequalities. Thanks for the heads up. $\endgroup$
    – Edmund
    Dec 29, 2015 at 13:18
3
$\begingroup$

OK, the related post I linked above may be too long, so let me extract the relevant part:

Pick[#, UnitStep[# - 6], 0] &@ls

Just for fun, here's a somewhat strange solution:

ls /. $_ /; $ >= 6 :> (## &[])
$\endgroup$
3
$\begingroup$

Although Select is the classical Mathematica function for doing what you ask, in V10.2 or later one can map an If expression (for some a more natural way to express the problem) and get the desired results.

SeedRandom[42]; data = RandomInteger[20, 100];
If[# < 6, #, Nothing] & /@ data

{4, 2, 1, 0, 4, 3, 0, 1, 4, 2, 5, 5, 3, 1, 2, 1, 1, 1, 2, 4, 5, 0, 5, 3, 1, 0, 3, 4, 5, 3, 5}

This is likely to run slower the Select, but will run much faster than a For-loop.

$\endgroup$
3
  • 2
    $\begingroup$ One can still use If to solve the problem before v10.2, by using these instead of Nothing :). $\endgroup$
    – xzczd
    Dec 29, 2015 at 5:15
  • $\begingroup$ I find: " Select items < 6 ", to be a fairly natural way to express the problem. $\endgroup$
    – Edmund
    Dec 29, 2015 at 17:42
  • $\begingroup$ @Edmund. I do too. But others don't. Note that I qualified my statement with "some". $\endgroup$
    – m_goldberg
    Dec 29, 2015 at 23:16

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.