Re: Position[] pattern matching
- To: mathgroup at smc.vnet.net
- Subject: [mg4254] Re: Position[] pattern matching
- From: Robert Villegas <villegas>
- Date: Sun, 23 Jun 1996 03:08:25 -0400
- Sender: owner-wri-mathgroup at wolfram.com
> I just ran into a strange pattern-matching problem: > > I'm reading some infomation from a disk file with > > fInfo = ReadList[ > "NDEC:EWW:RODDAT.PRN", > {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 ==== [MESSAGE SEPARATOR] ====