Mark Berryman wrote: > I have been tasked with converting all of the network utilities I've written > over the years in MUMPS into a language likely to be known by more people. > Most of it will be converted to Perl. So far the conversion hasn't presented > to many difficulties but there is one construct for which I have not been able > to derive a close equivalent. To wit:
> MUMPS arrays use alphanumeric indicies with a defined collating order. > Numeric > subscripts collate first, in numeric order, followed by string subscripts in > ASCII order. Thus, an array with the following indicies would collate in this > order: -2,-1,0,1,2,9,100,101.5,A,E,H,a,c,z etc. MUMPS arrays are also sparse > arrays and are multidimensional. However, for this question, it is okay to > assume an array with only one dimension. > The MUMPS language provides a function, called $ORDER, which takes an argument > and returns the next index that exists in the array that would come after the > supplied argument (a 2nd argument can be used to cause the function to return > the previous index instead of the next index). For example, given an array > with the index values given above, if I asked for the next index after 0, I > would get 1; the next index after 50 would return 100; the next index after > "Z" > would return "a"; etc. > My question: is there any way to approach similar functionality in Perl? Any > non-numeric arrays in my code are being converted to Perl hashes. I can > retrieve the value of a specific key, and I can use a for loop to go through > every key/value pair but, is there any way of doing something similar to > $ORDER without have to scan the entire hash? I think *somebody* has to scan the whole hash sometime, but it doesn't have to be explicitly in your code. Somebody who knows something should respond to this, really, but a WAG at how to do this, if your hash is static once set up: my $ordinal, $index, %ordinalhash, %indexhash; $ordinal = 0; foreach $index (sort keys %yourhash) { $ordinal++; $ordinalhash{$ordinal} = $index; $indexhash($index) = $ordinal; } To get your "what is the next index after this index", you can do $next_index = $ordinal_hash{$indexhash{$this_index}+1}; and for the previous index $previous_index = $ordinal_hash{$indexhash{$this_index}-1}; (In principle, although you have to check your values for undefinedness.) [It seems inelegant to subvert what's basically an array lookup into _two_ hashes, but I can't right this second think of an array way to do it that doesn't involve your coding a binary search or something to find your index, while this lets Perl's highly optimized hash search code do that for you. But in any case, there's more than one way to do it.] > Also, is there any defined order in which a hash is stored? I probably ought to know that. I _suspect_ it's just stored in the order you inserted stuff into it. I really don't know how much garbage collection goes on during runtime. -- Alan -- =============================================================================== Alan Winston --- [EMAIL PROTECTED] Disclaimer: I speak only for myself, not SLAC or SSRL Phone: 650/926-3056 Paper mail to: SSRL -- SLAC BIN 99, 2575 Sand Hill Rd, Menlo Park CA 94025 ===============================================================================