Re: selecting from lists
- To: mathgroup at smc.vnet.net
- Subject: [mg6139] Re: [mg6120] selecting from lists
- From: "w.meeussen" <w.meeussen at solair4b.eunet.be>
- Date: Sun, 23 Feb 1997 00:10:52 -0500
- Sender: owner-wri-mathgroup at wolfram.com
At 23:46 21-02-97 -0500, you wrote:
>The problem: given an arbitrary list v and a list b of the same
>length, whose entries are all Boolean (True or False), construct a
>function s[v, b] whose result is a list consisting only of those
>entries of v for which the corresponding entries in b are True. For
>example,
>
> v = {3, 82, 7, -12, 5};
> b = {False, True, True, False};
> s[v, b]
>{82, 7}
>
>Of course, a looping solution is obvious. But I want something that
>works on the entire list at once (as in the APL or J programming
>languages, where this sort of thing is utterly trivial). The best
>I've come up with so far is the following:
>
> bpick[x_, b_] := If[b, {x}, {}]
> SetAttributes[bpick, Listable]
> s[v_, b_] := Flatten[bpick[v, b]]
>
>Is there some nicer, more direct way? No Table's, Do's, or For's,
>please!
>
>Actually, the general problem as I formulated it above is just the tip
>of the iceberg of things that are giving me trouble in Mathematica
>that are so easy for me in APL or J. For example, construct a
>function firstnonzero that returns the index of the first nonzero
>entry in a list (or, more generally, the first entry in a list
>satisfying a given property). Here the best I've come up with that
>avoids explicit looping is:
>
> nonzero[x_] != 0; SetAttributes[nonzero, Listable]
> firstnonzero[v_] := First[s[Range[Length[v]], nonzero[v]]]
>
>In these and similar problems, I have the feeling that there ought to
>be some slick approach using patterns, but I don't see how to do it.
>
>Any help in putting me onto the right track in "Mathematica thinking"
>about such problems would be appreciated.
>
>--
> Murray Eisenberg Internet: murray at math.umass.edu
> Mathematics & Statistics Dept. Voice: 413-545-2859 (W)
> University of Massachusetts 413-549-1020 (H)
> Amherst, MA 01003 Fax: 413-545-1801
>
>
why not :
In[7]:=
Part[v,Flatten at Position[b,True]]
Out[7]=
{82,7}
and
In[19]:=
li={a,Null,33,33.7,False,Pi,1+x+x^2,"anything",{1},f[x]};
In[20]:=
Position[li,_Integer]
Out[20]=
{{3},{7,1},{7,3,2},{9,1}}
In[26]:=
Position[li,_Symbol,Heads->False]
Out[26]=
{{1},{2},{5},{6},{7,2},{7,3,1},{10,1}}
the list element "1+x+x^2" is Plus[1,x,Power[x,2]]
that's why the levels are nested.
you might want to replace the pattern test by a pure-function test:
In[28]:=
Position[li,t_/;(Sqrt[t]>5)]
Out[28]=
{{3},{4}}
meaning 'anything,(temporarily called t)with the condition that (the "/;")
meets the condition Sqrt[t]>5.
Of course, the function Sqrt could be a pure function too :
Power[#,1/2]& or (1-#+#^2)& or whatever ...
have fun,
Dr. Wouter L. J. MEEUSSEN
w.meeussen at solair4b.eunet.be