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
===============================================================================

Reply via email to