MathGroup Archive 1996

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Position[] pattern matching

  • To: mathgroup at
  • Subject: [mg4254] Re: Position[] pattern matching
  • From: Robert Villegas <villegas>
  • Date: Sun, 23 Jun 1996 03:08:25 -0400
  • Sender: owner-wri-mathgroup at

> I just ran into a strange pattern-matching problem:
> I'm reading some infomation from a disk file with
> fInfo = ReadList[
> 		{Word, Word, Word, Word, Word, Word, Word,
> 		Number, Number, Number, Number}
> ]
> Now, I want all records whose 4th word starts with an "L":

The 'Select' command will do this:

   Lrecords = Select[fInfo, StringTake[#[[4]], 1] == "L" & ]

About the error messages returned by Position:

> Position[
> 	fInfo,
> 	x_/;(StringTake[ x[[4]], 1 ] == "L")
> ]
> Part::partd: Part specification List[[4]]
>      is longer than depth of object.
> Part::partd: Part specification List[[4]]
>      is longer than depth of object.
> Part::partd: Part specification 002[[4]]
>      is longer than depth of object.
> General::stop:
>    Further output of Part::partd
>      will be suppressed during this calculation.
> Out[29]=
> {{5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15},
>   {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23}, {24}, {25},
>   {26}, {27}, {28}, {29}, {30}, {31}, {32}, {45}, {46}, {47},
>   {48}, {49}, {50}, {51}, {52}, {53}, {54}, {55}, {56}}

The Position command is very thorough:  it checks absolutely every
subexpression to see if it matches the requested pattern.  This
includes heads such as List, atoms such as strings or numbers,
and everything in between.  You were on the right track to restrict
the search to level 1, but level 1 still contains one thing you
aren't interested in testing:  the head List of the entire expression fInfo.
To prevent Position from testing heads, include the option Heads->False:

   Position[fInfo, record_ /; StringTake[record[[4]], 1] == "L",
     {1}, Heads->False]

The reason the head of fInfo is considered to be at level 1 is that the
position, or _part specification_, of the head is {0}, which is a list of
length 1.  Any subexpression's position is given by a list of integers,
which can be thought of as coordinates.  The _level_ of the subexpression
can be defined as the length of this list.  The position is allowed to
contain one or more 0's, indicating that the subexpression is a head, or
is contained in one (which can happen if there are heads that are themselves
complex expressions instead of mere symbols).

> P.S., a pet peeve: why can I say
> 							Select[ fInfo,  
(#[[4]] == somethingorother )& ]
> but need to say
> 							Position[ fInfo, 	 
x_/;x[[4]] == somethingorother) ]
> Shouldn't these allow the same formulation of the patten-match
> requirements?

Select takes a boolean function f and finds elements x such that
f[x] is True.

Position, and related functions such as Cases, DeleteCases, and MemberQ,
takes a structural pattern p and finds elements x which match the structure
described by p (essentially MatchQ[x, p], though MatchQ isn't called directly).

It is more common to have a structure to match than a boolean test
to apply.  That's why most of these commands take a pattern, not
a function.  But Select is provided for situations where you do have
a function you want to apply to prospective elements.

If you want to specify a test function in a pattern, you can do so in
PatternTest:  x_?test.  Example:

   Position[fInfo, record_?( #[[4]] == somethingorother & ),
     {1}, Heads->False]

Beware that the ? operator has a very high precedence, so the test
function that follows it should be enclosed in parentheses.

Robby Villegas


  • Prev by Date: Display of 3D contours in 2D
  • Next by Date: Re: help! to input data...
  • Previous by thread: Position[] pattern matching
  • Next by thread: Re: Position[] pattern matching