You do it as an array of one-dimensional arrays. One useful trick can
be, if an element can't take many different values, an array of strings
can work too.
Mark
As Mark said, postscript doesn't have multi-dimensional arrays per
se.
But since an array is a first-class object, arrays can contain arrays
to an arbitrary depth.
Probably the easiest way to create an n-element array of m-element
arrays of null is:
[ n { m array } repeat ]
So if you define A to yield a 2 by 2 array,
/A [ 2 { 2 array } repeat ] def
you can set element (x,y) by getting row x and putting into column y.
A 0 get 0 1 put
A 0 get 1 0 put
A 1 get 0 0 put
A 1 get 1 1 put
This would be equivalent to constructing the array more directly:
/A [ [ 1 0 ] [ 0 1 ] ] def
For retrieving element (0,0) you can do:
A 0 get 0 get
Or the "shortcut":
A [ 0 0 ] { get } forall
HTH
L
X
T
I was intrigued enough to explore whether the "shortcut" could be
used for both put and get. The result is a little complicated, but
it works.
%!
% array {all-but} {last} forall-1 -
% "forall minus one"
% execute {all-but} for elements 0 .. n-2
% execute {last} for element n-1
/STATIC 2 array def
/forall-1 {
<<
0 { pop pop pop } % length == 0: do nothing
1 { exch pop forall } % length == 1: do {last}
>>
3 index length %dup =
2 copy known { get exec }{ pop pop
2 index 0
1 index length
1 sub getinterval %dup ==
3 1 roll
4 -1 roll
dup length 1 sub get %dup =
exch
//STATIC astore pop
forall
//STATIC aload pop
exec
} ifelse
} def
% m-array [ indices ] mget element(indices)
/mget {
{ get } forall
} def
% m-array [ indices ] value mput -
/mput {
3 1 roll { get } { 3 -1 roll put } forall-1
} def
/A
[ 5 {
[ 5 {
[ 5 { null } repeat ]
} repeat ]
} repeat ] def
A [ 4 4 4 ] 37 mput
A [ 4 4 4 ] mget
=
currentfile flushfile
!!gs %
GPL Ghostscript 8.62 (2008-02-29)
Copyright (C) 2008 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
37
GS>GS>
Thank you very much for the very helpful answers.
One advantage of postscript polymorphism is that all composite
objects
can be accessed using the same syntax with get and put.
/A [ [ 16#30 16#31 16#32 16#33 ]
[ 16#34 16#35 16#36 16#37 ] ] def
/B [ (0123) (4567) ] def
/C << 0 (0123) 1 (4567) >> def
A [ 0 0 ] {get} forall
B [ 0 0 ] {get} forall
C [ 0 0 ] {get} forall
All three of these fetch the integer 48 (ascii zero) using 0 get 0
get.
But one is an array of arrays of integers, one is an array of strings,
and the third is a dictionary of strings with integer keys.
As an alternative to the concept 'Arrays in Array':
Use strictly onedimensional arrays and memory mapping functions.
Here comes Matrix-Library (Linear Algebra etc.)
Description in chapter 18:
http://www.fho-emden.de/~hoffmann/pstutor22112002.pdf
Source code (executable), rename *.txt as *.eps:
http://www.fho-emden.de/~hoffmann/matrixlib.txt
The programming style is very basic and therefore understandable.
Lacking speed is no issue for my applications.
Best regards --Gernot Hoffmann