Re: harder parts of list
- To: mathgroup at smc.vnet.net
- Subject: [mg15589] Re: harder parts of list
- From: Hartmut Wolf <hw at gsmail01.darmstadt.dsh.de>
- Date: Thu, 28 Jan 1999 04:23:22 -0500 (EST)
- Organization: debis Systemhaus
- References: <786uft$29u@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Dear Arnold
Arnold Knopfmacher schrieb:
>
> This seems to be a harder list parts problem. Given a list like
>
> lst={{4,2,3,1},{3,1,5},{2,4,3}}
>
> I wish to select the elements in each sublist that are smaller than the
> first entry in that sublist.
> So for the above lst the output should be {{2,3,1},{1},{}}. How can I
> do this with Select or Cases?
>
> Using pattern matching this works
>
> rule1={a_,b___,c_,d___}:>{a,b,d} /;c>a
>
> (# //. rule1)& /@ lst
>
> {{4,2,3,1},{3,1},{2}}
>
> Rest /@ %
>
> {{2,3,1},{1},{}}
>
> Thanks
> Arnold Knopfmacher
> Wiws University
> South Africa
You do have a solution with replacement rules, that works. In fact you
solved for "smaller or equal", as you see with lst2:
lst2= {{4,2,3,4},{3,1,5},{1,1,1},{0}}
(# //. rule1)& /@ lst2
then gives:
{{4,2,3,4},{3,1},{1,1,1},{0}}
and then
Rest /@ %
results to:
{{2,3,4},{1},{1,1},{}}
If you want only to keep the "smaller" elements then just throw away
those greater or equal:
rule2={a_,b___,c_,d___}:>{a,b,d} /;c>=a
which gives
(# //. rule2)& /@ lst2
{{4,2,3},{3,1},{1},{0}}
Rest /@ %
{{2,3},{1},{},{}}
You can have a solution with Select, which differs a little bit when
selecting for elements "smaller or equal" (1) or "smaller" (2).
For (1) try:
Function[x,Rest[Select[x, (# <= x[[1]]) &]]] /@ lst2
{{2,3,4},{1},{1,1},{}}
for (2) Rest could result to an error Rest::norest, but you don't need
Rest then (because you first sublist elements won't be kept), so
Function[x,Select[x, (# < x[[1]]) &]] /@ lst2
{{2,3},{1},{},{}}
This wasn't the case with your replacement rule, since you explicitly
demanded and needed(!) to keep the first element.
Perhaps your real problem was to nest two pure functions. Use Function
to give unambiguous names to the arguments.
With Cases you don't have that problem, since the other variable is a
pattern you have to give a name to anyways:
Rest[Cases[#, y_ /; y <= #[[1]] ]]& /@ lst2
{{2,3,4},{1},{1,1},{}}
for (1) and for (2) respectively:
Cases[#, y_ /; y < #[[1]] ]& /@ lst2
{{2,3},{1},{},{}}
Back to your own solution, of course you can make a one-liner:
Rest[# //. rule1]& /@ lst2
{{2,3,4},{1},{1,1},{}}
and
Rest[# //. rule2]& /@ lst2
{{2,3},{1},{},{}}
Even more elegantly define
selectAccordingTo = Function[x, Rest[x //. #]]&
then
selectAccordingTo[rule1] /@ lst2
{{2,3,4},{1},{1,1},{}}
and
selectAccordingTo[rule2] /@ lst2
{{2,3},{1},{},{}}
As often there are a hundred of possibilities, and certainly some are
more elegant, performant, handy, or ... what you like.
Hartmut