
[mg6137] Re: [mg6120] selecting from lists
Posted:
Feb 23, 1997 12:23 AM


>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! >
Like the passengers of the Titanic, I will attend to the tip of the iceberg only ......
Here is a combination of Mathematica list handling functions and a pure function that will do what you ask above.
In[16]:=
v = {3, 82, 7, 12, 5}; b = {False, True, True, False, True};
(* list b was added to to make the lists the same length *)
Here it is in steps:
In[21]:= pairs=Transpose[{v, b}] Out[21]= {{3, False}, {82, True}, {7, True}, {12, False}, {5, True}}
In[22]:= Select[pairs, #[[2]]&]
Out[22]= {{82, True}, {7, True}, {5, True}}
In[23]:= Map[First, %] Out[23]= {82, 7, 5}
Here are the steps rolled into a function.
In[24]:= f[x_List, y_List] := Map[First, Select[Transpose[{x,y}], #[[2]]&]]
In[25]:= f[v, b] Out[25]= {82, 7, 5}
Tom Zeller
Wait! what is that under the water?!
>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@math.umass.edu > Mathematics & Statistics Dept. Voice: 4135452859 (W) > University of Massachusetts 4135491020 (H) > Amherst, MA 01003 Fax: 4135451801

