Grey Fox has asked for the wisdom of the Perl Monks concerning the following question:
Is it possible to use the split function to load a data hash. I am trying to split a list of names and address's which are seperated by commas from a text file.
Thanks;
Perl - Hours to learn lifetime to master.
UPDATE: I am new to perl and still trying to wrap my head around the split, hash, and map functions. I have seen the split and map functions used to load hashs. Originally I'm from a legacy cobol environment, but have had some experience with client server before. Any good references for explaining split, hash and map. Most of what I have found is pretty cryptic.
Thanks
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Using Split to load a hash
by shmem (Chancellor) on Aug 19, 2006 at 14:22 UTC | |
update after the OP's update Documentation You get, as you might know already, documentation for split, hash and map typing e.g. perldoc -f split on the command line of your shell. About perl being cryptic The cryptiness of perl expressions will vanish as you become familiar with it's main concepts, two of them being data types (scalars, arrays, hashes and references, which are, well, scalars) and context. The latter is perl's curse and blessing and the origin of much of it's perceived cryptiness, because many functions behave different depending on the context they are invoked in. Even simple assignments do different things to the right-hand-side before the assignment is done to the left-hand-side of =, depending on what type the lvalue is. The text file contains just one record per line, right?
in, say, a file named addrfile.txt; then I would say e.g. (TIMTOWTDI - There's More Than One Way To Do It) which results in and looks pretty cryptic. Explanation, per line (except empty ones :-) Line 1 tells the OS which interpreter to use. Line 8 is where things get interesting. It "just" contains an invocation of chop (LIST) There. The result of map is a sequence of key/value pairs, which are assigned to a hash, which is then chopped. Line 12 just prints out the hash as key => value. The above could be written more verbosely like this: but in order to address most of the points in your post I showed you the "cryptic" one first :-) Also, if you examine this code, you will find that the contents of the hash will allocate memory twice with both my examples - first building up a list, then assigning that list to a hash. For small files that's ok, but for larger files you'd say rather as shown by other replies to your post. --shmem update: small fixes (grammar and such) _($_=" "x(1<<5)."?\n".q·/)Oo. G°\ / /\_¯/(q / ---------------------------- \__(m.====·.(_("always off the crowd"))."· ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print} | [reply] [d/l] [select] |
Re: Using Split to load a hash
by rodion (Chaplain) on Aug 19, 2006 at 15:06 UTC | |
Update: Added ",$_,2" to the split, to handle addresses with a comma, and modified test cases acordingly | [reply] [d/l] |
by izut (Chaplain) on Aug 19, 2006 at 17:59 UTC | |
Another possible method (borrowed from "Perl for System Administrators"):
This will possible fail if the second field has comma. Maybe we can work it out to prevent that :-)
Igor 'izut' Sutton | [reply] [d/l] |
Re: Using Split to load a hash
by davido (Cardinal) on Aug 19, 2006 at 15:43 UTC | |
Yes, you can use split for that. First, open the file. Next, iterate over its content. Chomp the line. If the remaining line is empty, next to the next line (this is just a precaution). Assuming the line isn't blank, split it on comma, assigning the results to two lexical variables. Then use one variable as the key, and one as the value in adding an element to your hash. Finally, close the file. Let us know which part of that task has you stumped. Dave | [reply] [d/l] |
Re: Using Split to load a hash
by BrowserUk (Patriarch) on Aug 19, 2006 at 16:24 UTC | |
Provided the name doesn't contain commas, then it won't matter if the address does, provided you use 3rd parameter to split. This is a number that specifies how many fields to split the input into. By setting this to 2, everything before the first comma will be treated as the first field--the name. And everything after that first comma, including more commas, will become the second field:
Produces:
Note that the addresses are unchomped. Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
Re: Using Split to load a hash
by graff (Chancellor) on Aug 19, 2006 at 16:11 UTC | |
(In fact, even if your input data is really simple and has no quoted fields containing commas, you might still want to use one of those modules -- or at least look at their docs.) | [reply] |
Re: Using Split to load a hash
by ysth (Canon) on Aug 20, 2006 at 17:11 UTC | |
| [reply] |
Re: Using Split to load a hash
by tanyeun (Sexton) on Aug 20, 2006 at 13:12 UTC | |
maybe it's not a concise way but I find it useful any comments will be pleased^_^ | [reply] [d/l] |
by wfsp (Abbot) on Aug 20, 2006 at 13:59 UTC | |
Perhaps you could consider loading you data into one data structure instead of three arrays. You might also want a more general purpose approach where it would be easier to change the number and name of the columns. Putting aside the question of commas inside the fields and any other error checking one approach might be like this. It creates an array of hashes. If you were thinking of using something like HTML::Template for your output this would be very handy! :-)
output:
Hope that helps.
| [reply] [d/l] [select] |
Re: Using Split to load a hash
by Anonymous Monk on Apr 27, 2010 at 12:23 UTC | |
| [reply] [d/l] |
by umasuresh (Hermit) on Apr 30, 2010 at 17:33 UTC | |
Note: DATA should be tab delimited for this to work | [reply] [d/l] |