Create a two-dimensional array at runtime

From Rosetta Code

Jump to: navigation, search
Task
Create a two-dimensional array at runtime
You are encouraged to solve this task according to the task description, using any language you may know.

Data Structure
This illustrates a data structure, a means of storing data within a program.

You may see other such structures in the Data Structures category.

Get two integers from the user, then create a two-dimensional array where the two dimensions have the sizes given by those numbers, and which can be accessed in the most natural way possible. Write some element of that array, and then output that element. Finally destroy the array if not done by the language itself.

Contents

[edit] Ada

with Ada.Text_Io; use Ada.Text_Io;
with Ada.Float_Text_Io; use Ada.Float_Text_Io;
with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;
 
procedure Two_Dimensional_Arrays is
type Matrix_Type is array(Positive range <>, Positive range <>) of Float;
Dim_1 : Positive;
Dim_2 : Positive;
begin
Get(Item => Dim_1);
Get(Item => Dim_2);
-- Create an inner block with the correctly sized array
declare
Matrix : Matrix_Type(1..Dim_1, 1..Dim_2);
begin
Matrix(1, Dim_2) := 3.14159;
Put(Item => Matrix(1, Dim_2), Fore => 1, Aft => 5, Exp => 0);
New_Line;
end;
-- The variable Matrix is popped off the stack automatically
end Two_Dimensional_Arrays;

[edit] ALGOL 68

main:(
print("Input two positive whole numbers separated by space and press newline:");
[read int,read int] INT array;
array[1,1]:=42;
print (array[1,1])
)

[edit] APL

Arrays are an integral part of APL. Array size, shape, and data type can be easily manipulated at runtime.

array←m n ⍴ 0 ⍝ array of zeros with shape of m by n.
 
array[1;1]←73 ⍝ assign a value to location 1;1.
 
array[1;1] ⍝ read the value back out
 
⎕ex 'array' ⍝ erase the array
 

[edit] AppleScript

AppleScript has no array, but an AppleScript list can be used in a multidimensional fashion. There's no issue with their dimensions, they grow while adding elements. Memory allocation is dynamic.

set R to text returned of (display dialog "Enter number of rows:" default answer 2) as integer
set c to text returned of (display dialog "Enter number of columns:" default answer 2) as integer
set array to {}
repeat with i from 1 to R
set temp to {}
repeat with j from 1 to c
set temp's end to 0
end repeat
set array's end to temp
end repeat
 
-- Address the first column of the first row:
set array's item 1's item 1 to -10
 
-- Negative index values can be used to address from the end:
set array's item -1's item -1 to 10
 
-- Access an item (row 2 column 1):
set x to array's item 2's item 1
 
return array
 
-- Destroy array (typically unnecessary since it'll automatically be destroyed once script ends).
set array to {}
 

[edit] AutoIt

Global $array[1][1]
$array[0][0] = 42
MsgBox(0,"",$array[0][0])
 

[edit] AWK

AWK has no multidimensional array; but AWK arrays (which are Associative array indeed) can be used also in a multidimensional fashion. Since AWK arrays are associative arrays, there's no issue in their dimensions: they grow while adding new key-value pair.

/[0-9]+ [0-9]+/ {
for(i=0; i < $1; i++) {
for(j=0; j < $2; j++) {
arr[i, j] = i*j
}
}
 
# how to scan "multidim" array as explained in the GNU AWK manual
for (comb in arr) {
split(comb, idx, SUBSEP)
print idx[1] "," idx[2] "->" arr[idx[1], idx[2]]
}
}

[edit] BASIC

Works with: QuickBasic version 4.5

CLS
INPUT a, b 'inputs need to be separated by commas
DIM array (1 TO a, 1 TO b)
array(1,1) = 42
PRINT array(1,1)
ERASE array

[edit] C

[edit] C99

Works with: C99

#include <stdio.h>
 
int main(int argc, char **argv) {
 
int user1 = 0, user2 = 0;
printf("Enter two integers. Space delimited, please: ");
scanf("%d %d",&user1, &user2);
int array[user1][user2];
array[user1/2][user2/2] = user1 + user2;
printf("array[%d][%d] is %d\n",user1/2,user2/2,array[user1/2][user2/2]);
 
return 0;
}

[edit] Traditional Style

This style is supported by all 'C' compilers.

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int user1 = 0, user2 = 0;
int *a1, **array, row;
 
printf("Enter two integers. Space delimited, please: ");
scanf("%d %d",&user1, &user2);
 
a1 = malloc(user1*user2*sizeof(int));
array = malloc(user2*sizeof(int*));
for (row=0; row<user1; row++) array[row]=a1+row*user2;
 
array[user1/2][user2/2] = user1 + user2;
printf("array[%d][%d] is %d\n",user1/2,user2/2,array[user1/2][user2/2]);
free(array);
free(a1);
return 0;
}

This style also supports more efficient memory utilization if you're only using a portion of the array. If you only need the upper right half of a square array, you can do something like the following.

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int user1 = 0;
int space_needed;
int *a1, **array;
int row, col;
 
printf("Enter size of array: ");
scanf("%d",&user1);
 
space_needed = (user1+1)*user1/2;
a1 = malloc(space_needed);
array = malloc(user1*sizeof(int*));
for (row=0,offset=0; row<user1; offset+=(user1-row), row++) {
array[row]=a1+offset-row;
for (col=row; col<user1; col++)
array[row][col] = 1+col-row;
}
for (row=0; row<user1; row++)
printf("%d ", array[row][user1-1]);
printf("\n");
 
free(array);
free(a1);
return 0;
}

This approach most closely matches the C99 example, as alloca allocates on the stack, rather than the heap, as malloc does.

#include <stdio.h>
#include <alloca.h>
int main(int argc, char **argv)
{
int user1 = 0, user2 = 0;
int *a1, **array, row;
 
printf("Enter two integers. Space delimited, please: ");
scanf("%d %d",&user1, &user2);
 
a1 = alloca(user1*user2*sizeof(int));
array = alloca(user1*sizeof(int*));
for (row=0; row<user1; row++) array[row]=a1+row*user2;
 
array[user1/2][user2/2] = user1 + user2;
printf("array[%d][%d] is %d\n",user1/2,user2/2,array[user1/2][user2/2]);
return 0;
}

[edit] C++

With language built-in facilities:

#include <iostream>
#include <istream>
#include <ostream>
 
int main()
{
// read values
int dim1, dim2;
std::cin >> dim1 >> dim2;
 
// create array
double* array_data = new double[dim1*dim2];
double** array = new double*[dim1];
for (int i = 0; i < dim1; ++i)
array[i] = array_data + dim2*i;
 
// write element
array[0][0] = 3.5;
 
// output element
std::cout << array[0][0] << std::endl;
 
// get rid of array
delete[] array;
delete[] array_data;
}

Using std::vector from the standard library:

#include <iostream>
#include <istream>
#include <ostream>
#include <vector>
 
int main()
{
// read values
int dim1, dim2;
std::cin >> dim1 >> dim2;
 
// create array
std::vector<std::vector<double> > array(dim1, std::vector<double>(dim2));
 
// write element
array[0][0] = 3.5;
 
// output element
std::cout << array[0][0] << std::endl;
 
// the array is automatically freed at the end of main()
}

[edit] D

import std.stdio: writef, writefln, readln;
import std.conv: toInt;
import std.string: strip;
 
void main() {
writef("Give me the numer of rows: ");
int nrow = toInt(readln().strip());
 
writef("Give me the numer of columns: ");
int ncol = toInt(readln().strip());
 
auto array = new float[][](nrow, ncol);
array[0][0] = 3.5;
writefln("The number at place [0 0] is ", array[0][0]);
}

[edit] Clean

import StdEnv
 
Start :: *World -> { {Real} }
Start world
# (console, world) = stdio world
(_, dim1, console) = freadi console
(_, dim2, console) = freadi console
= createArray dim1 (createArray dim2 1.0)

[edit] C#

 
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter two integers. Space delimited please: ");
string s = Console.ReadLine();
 
int[,] myArray=new int[(int)s[0],(int)s[2]];
myArray[0, 0] = 2;
Console.WriteLine(myArray[0, 0]);
 
Console.ReadLine();
}
}
 

[edit] Common Lisp

(let ((d1 (read))
(d2 (read)))
(assert (and (typep d1 '(integer 1))
(typep d2 '(integer 1)))
(d1 d2))
(let ((array (make-array (list d1 d2) :initial-element nil))
(p1 0)
(p2 (floor d2 2)))
(setf (aref array p1 p2) t)
(print (aref array p1 p2))))

The assert will allow the user to reenter the dimensions if they are not positive integers.

[edit] Factor

Factor doesn't provide any support for easy access of 2d arrays. But since factor's written in factor, we can just add it and it's just as good :)

USING: io kernel math.matrices math.parser prettyprint
sequences ;
IN: rosettacode.runtime2darray
 
: set-Mi,j ( elt {i,j} matrix -- )
[ first2 swap ] dip nth set-nth ;
: Mi,j ( {i,j} matrix -- elt )
[ first2 swap ] dip nth nth ;
 
: example ( -- )
readln readln [ string>number ] bi@ zero-matrix ! create the array
[ [ 42 { 0 0 } ] dip set-Mi,j ] ! set the { 0 0 } element to 42
[ [ { 0 0 } ] dip Mi,j . ] ! read the { 0 0 } element
bi ;

[edit] Forth

: cell-matrix
create ( width height "name" ) over , * cells allot
does> ( x y -- addr ) dup cell+ >r @ * + cells r> + ;
 
5 5 cell-matrix test
 
36 0 0 test !
0 0 test @ . \ 36

Library: Forth Scientific Library

INTEGER DMATRIX my-matrix{{
& my-matrix{{ 8 9 }}malloc
 
8 my-matrix{{ 3 4 }} !
my-matrix{{ 3 4 }} @ .
 
& my-matrix{{ }}free

[edit] Fortran

In Fortran 90 and later

PROGRAM Example
 
IMPLICIT NONE
INTEGER :: rows, columns, errcheck
INTEGER, ALLOCATABLE :: array(:,:)
 
WRITE(*,*) "Enter number of rows"
READ(*,*) rows
WRITE(*,*) "Enter number of columns"
READ(*,*) columns
 
ALLOCATE (array(rows,columns), STAT=errcheck) ! STAT is optional and is used for error checking
 
array(1,1) = 42
 
WRITE(*,*) array(1,1)
 
DEALLOCATE (array, STAT=errcheck)
 
END PROGRAM Example

[edit] F#

open System
 
let width = int( Console.ReadLine() )
let height = int( Console.ReadLine() )
let arr = Array2D.create width height 0
arr.[0,0] <- 42
printfn "%d" arr.[0,0]

[edit] Haskell

 doit n m = a!(0,0) where a = array ((0,0),(n,m)) [((0,0),42)]

[edit] HicEst

REAL :: array(1)
 
DLG(NameEdit=rows, NameEdit=cols, Button='OK', TItle='Enter array dimensions')
 
ALLOCATE(array, cols, rows)
array(1,1) = 1.234
WRITE(Messagebox, Name) array(1,1)

[edit] Icon and Unicon

All Icon and Unicon data objects are automatically reclaimed. Multiply dimensioned arrays are arrays of arrays in both languages.

[edit] Icon

procedure main(args)
nr := integer(args[1]) | 3 # Default to 3x3
nc := integer(args[2]) | 3
 
A := list(nr)
every !A := list(nc)
 
x := ?nr # Select a random element
y := ?nc
 
A[x][y] := &pi
write("A[",x,"][",y,"] -> ",A[x][y])
end

Sample output:

->ar 65 2
A[37][1] -> 3.141592654

[edit] Unicon

The Icon solution also works in Unicon.

[edit] IDL

The following is only for demonstration. No real program should just assume that the user input is valid, integer, large enough etc.

read, x, prompt='Enter x size:'
read, y, prompt='Enter y size:'
d = fltarr(x,y)
 
d[3,4] = 5.6
print,d[3,4]
;==> outputs 5.6
 
delvar, d

[edit] J

The natural ways of creating a two dimensional array in J are i. and $

   array1=:i. 3 4   NB. a 3 by 4 array with arbitrary values
array2=: 5 6 $ 2 NB. a 5 by 6 array where every value is the number 2

To update the upper left corner of the array with the value 99, you might use }

   array1=: 99 (<0 0)} array1

And, to retrieve that value you might use {

   (<0 0) { array1

Finally, J manages storage for you, so to delete the array, you could either have the name refer to a new value

   array1=: 0

or you could remove the name itself:

   erase'array1'

Putting these ideas together and adding a few frills:

task=: 3 : 0
'init new' =. 0;1 NB. values for initialization and alteration
array =. y $ init NB. create array of shape y
element =. < ? $ array NB. pick an atom of the array at random
array =. new element } array NB. amend that element to new value
element { array NB. return value of changed element
)

Passing two integers to task (as a list) satisfies the specifications for a two-dimensional array, but providing a longer list of integers accomplishes the same task on an array of as many dimensions as the count of integers given.

The type of the array is determined by the type of the values used in filling the array. E.g., alternate data types are obtained by substituting any of the following lines:

'init new' =. ' ';'x'           NB. literals
'init new' =. 1r2;2r3 NB. fractions
'init new' =. a: ; <<'Rosetta' NB. boxes

[edit] Java

import java.util.Scanner;
 
public class twoDimArray {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
 
int nbr1 = in.nextInt();
int nbr2 = in.nextInt();
 
double[][] array = new double[nbr1][nbr2];
array[0][0] = 42.0;
System.out.println("The number at place [0 0] is " + array[0][0]);
}
}

[edit] JavaScript

For the user input, requires JScript. The array processing is implementation agnostic.

var w = parseInt( get_input("Enter a width:") );
var w = parseInt( get_input("Enter a height:") );
 
// create the 2-D array
var a = new Array(h);
for (var i = 0; i < h; i++)
a[i] = new Array(w);
 
a[0][0] = 'foo';
WScript.Echo('a[0][0] = ' + a[0][0]);
 
a = null;
 
function get_input(prompt) {
output(prompt);
try {
return WScript.StdIn.readLine();
} catch(e) {
return readline();
}
}
function output(prompt) {
try {
return WScript.echo(prompt);
} catch(e) {
return print(prompt);
}
}

[edit] Logo

Works with: UCB Logo

make "a2 mdarray [5 5]
mdsetitem [1 1] :a2 0  ; by default, arrays are indexed starting at 1
print mditem [1 1] :a2  ; 0

[edit] Lua

function multiply(n, a, b) if a <= b then return n, multiply(n, a + 1, b) end end
 
a, b = io.read() + 0, io.read() + 0
matrix = {multiply({multiply(1, 1, b)}, 1, a)}
matrix[a][b] = 5
print(matrix[a][b])
print(matrix[1][1])

[edit] MATLAB

width = input('Array Width: ');
height = input('Array Height: ');
 
array = zeros(width,height);
 
array(1,1) = 12;
 
disp(['Array element (1,1) = ' num2str(array(1,1))]);

Sample Output:

Array Width: 18
Array Height: 12
Array element (1,1) = 12

[edit] MAXScript

a = getKBValue prompt:"Enter first dimension:"
b = getKBValue prompt:"Enter second dimension:"
arr1 = #()
arr2 = #()
arr2[b] = undefined
for i in 1 to a do
(
append arr1 (deepCopy arr2)
)
arr1[a][b] = 1
print arr1[a][b]

[edit] MUMPS

This example uses a two level tree to mimic an 2D array.

 
ARA2D
NEW X,Y,A,I,J
REARA
WRITE !,"Please enter two positive integers"
READ:10 !,"First: ",X
READ:10 !,"Second: ",Y
GOTO:(X\1'=X)!(X<0)!(Y\1'=Y)!(Y<0) REARA
FOR I=1:1:X FOR J=1:1:Y SET A(I,J)=I+J
WRITE !,"The corner of X and Y is ",A(X,Y)
KILL X,Y,A,I,J
QUIT
 

[edit] Objective-C

Being Objective-C derivated from C, the C solution works fine in Objective-C too.

The "OpenStep" frameworks (GNUstep, Cocoa) does not provide a class for multidimensional array; of course it can be implemented in several way (also as a wrapper for the plain C way of handling arrays). Here I show a straightforward use of the NSMutableArray class.

Works with: GNUstep Works with: Cocoa

#import <Foundation/Foundation.h>
 
int main()
{
int num1, num2, i, j;
NSMutableArray *arr;
 
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
scanf("%d %d", &num1, &num2);
 
NSLog(@"%d %d", num1, num2);
 
arr = [NSMutableArray arrayWithCapacity: (num1*num2)];
// initialize it with 0s
for(i=0; i < (num1*num2); i++) [arr addObject: [NSNumber numberWithInt: 0]];
 
// replace 0s with something more interesting
for(i=0; i < num1; i++) {
for(j=0; j < num2; j++) {
[arr replaceObjectAtIndex: (j*num1+i) withObject: [NSNumber numberWithInt: (i*j)]];
}
}
 
// access a value: I*num1+J, where I,J are the indexes for the bidimensional array
NSLog(@"%@", [arr objectAtIndex: (1*num1+3)]);
[pool release];
return 0;
}


[edit] Objeck

 
use IO;
 
bundle Default {
class TwoDee {
function : Main(args : System.String[]) ~ Nil {
DoIt();
}
 
function : native : DoIt() ~ Nil {
Console->GetInstance()->Print("Enter x: ");
x := Console->GetInstance()->ReadString()->ToInt();
 
Console->GetInstance()->Print("Enter y: ");
y := Console->GetInstance()->ReadString()->ToInt();
 
if(x > 0 & y > 0) {
array : Int[,] := Int->New[x, y];
array[0, 0] := 2;
array[0, 0]->PrintLine();
};
}
}
}
 

[edit] OCaml

let nbr1 = read_int ();;
let nbr2 = read_int ();;
let array = Array.make_matrix nbr1 nbr2 0.0;;
array.(0).(0) <- 3.5;;
print_float array.(0).(0); print_newline ();;

or using the module Bigarray:

let nbr1 = read_int ();;
let nbr2 = read_int ();;
let arr = Bigarray.Array2.create Bigarray.float32 Bigarray.c_layout nbr1 nbr2 ;;
arr.{0,0} <- 3.5;;
print_float arr.{0,0}; print_newline ();;

[edit] Oz

Oz does not have multi-dimensional arrays. But we can create an array of arrays (similarly to most examples on this page):

declare
%% Read width and height from stdin
class TextFile from Open.file Open.text end
StdIn = {New TextFile init(name:stdin)}
Width = {String.toInt {StdIn getS($)}}
Height = {String.toInt {StdIn getS($)}}
%% create array
Arr = {Array.new 1 Width unit}
in
for X in 1..Width do
Arr.X := {Array.new 1 Height 0}
end
%% set and read element
Arr.1.1 := 42
{Show Arr.1.1}

[edit] Pascal

Works with: GNU Pascal version 20060325, based on gcc-3.4.4

The following code is standard Extended Pascal (tested with gpc --extended-pascal):

program array2d(input, output);
 
type
tArray2d(dim1, dim2: integer) = array[1 .. dim1, 1 .. dim2] of real;
pArray2D = ^tArray2D;
 
var
d1, d2: integer;
data: pArray2D;
 
begin
{ read values }
readln(d1, d2);
 
{ create array }
new(data, d1, d2);
 
{ write element }
data^[1,1] := 3.5;
 
{ output element }
writeln(data^[1,1]);
 
{ get rid of array }
dispose(data);
end.


[edit] Perl

Works with: Perl version 5.x

Predefining an array (or multi-dimension array) size is unnecessary, Perl dynamically resizes the array to meet the requirements. Of course I'm assuming that the user is entering array size 0 based.

sub make_array($ $){
# get array sizes from provided params, but force numeric value
my $x = ($_[0] =~ /^\d+$/) ? shift : 0;
my $y = ($_[0] =~ /^\d+$/) ? shift : 0;
 
# define array, then add multi-dimensional elements
my @array;
$array[0][0] = 'X '; # first by first element
$array[5][7] = 'X ' if (5 <= $y and 7 <= $x); # sixth by eighth element, if the max size is big enough
$array[12][15] = 'X ' if (12 <= $y and 15 <= $x); # thirteenth by sixteenth element, if the max size is big enough
 
# loop through the elements expected to exist base on input, and display the elements contents in a grid
foreach my $dy (0 .. $y){
foreach my $dx (0 .. $x){
(defined $array[$dy][$dx]) ? (print $array[$dy][$dx]) : (print '. ');
}
print "\n";
}
}

The above is a bit verbose, here is a simpler implementation:

sub array {
my ($x, $y) = @_;
map {[ (0) x $x ]} 1 .. $y
}
 
my @square = array 3, 3;
 
# everything above this line is mostly redundant in perl,
# since perl would have created the array automatically when used.
# however, the above function initializes the array elements to 0,
# while perl would have used undef
#
# $cube[3][4][5] = 60 # this is valid even if @cube was previously undefined
 
$square[1][1] = 1;
print "@$_\n" for @square;
> 0 0 0
> 0 1 0
> 0 0 0

[edit] PicoLisp

(de 2dimTest (DX DY)
(let A (make (do DX (link (need DY))))
(set (nth A 3 3) 999) # Set A[3][3] to 999
(mapc println A) # Print all
(get A 3 3) ) ) # Return A[3][3]
 
(2dimTest 5 5)

Output:

(NIL NIL NIL NIL NIL)
(NIL NIL NIL NIL NIL)
(NIL NIL 999 NIL NIL)
(NIL NIL NIL NIL NIL)
(NIL NIL NIL NIL NIL)
-> 999

[edit] PL/I

 
/* First way using a controlled variable: */
 
declare A(*,*) float controlled;
get list (m, n);
allocate A(m,n);
get list (A);
put skip list (A);
 
/* The array remains allocated until the program terminates, */
/* or until explicitly destroyed using a FREE statement. */
 
free A;
 
 6.00000E+0000           5.00000E+0000           4.00000E+0000           3.00000E+0000           2.00000E+0000          
1.00000E+0000
 
 
/* Second way using a BEGIN block: */
 
get list (m, n);
begin;
declare A(m, n) float;
get list (A);
put skip list (A);
end;
 
/* The array is automatically destroyed then the block terminates. */
 
 1.00000E+0000           2.00000E+0000           3.00000E+0000           4.00000E+0000           5.00000E+0000          
6.00000E+0000 7.00000E+0000 8.00000E+0000 9.00000E+0000 1.00000E+0001
1.10000E+0001 1.20000E+0002
 
 
/* Third way using a PROCEDURE block: */
 
get list (m, n);
call S (m, n);
S: procedure (m, n);
declare A(m, n) float;
get list (A);
put skip list (A);
end S;
 
/* The array is automatically destroyed when the procedure terminates. */
 
 
1.00000E+0000 2.00000E+0000 3.00000E+0000 4.00000E+0000 5.00000E+0000
6.00000E+0000 7.00000E+0000 8.00000E+0000 9.00000E+0000 1.00000E+0001
1.10000E+0001 1.20000E+0001 1.30000E+0001 1.40000E+0001 1.50000E+0001
1.60000E+0001 1.70000E+0001 1.80000E+0001 1.90000E+0001 2.00000E+0001
 

[edit] Pop11

vars itemrep;
incharitem(charin) -> itemrep;
;;; Read sizes
vars n1 = itemrep(), n2= itemrep();
;;; Create 0 based array
vars ar = newarray([0 ^(n1 - 1) 0 ^(n2 - 1)], 0);
;;; Set element value
15 -> ar(0, 0);
;;; Print element value
ar(0,0) =>
;;; Make sure array is unreferenced
0 -> ar;

Pop11 is garbage collected so there is no need to destroy array. However, the array is live as long as variable ar references it. The last assignment makes sure that we loose all our references to the array turning it into garbage.

Pop11 arrays may have arbitrary lower bounds, since we are given only size we create 0 based array.

[edit] PureBasic

If OpenConsole()
Define x, y
 
Print("Input X-Size: ")
x = Val(Input())
 
Print("Input Y-Size: ")
y = Val(Input())
 
Dim a(x,y) ; Should really check if x & y are larger then 1, but that would be less fun....
 
a(1,1)=Random(1000)
PrintN("a(1,1)= " + Str(a(1,1)) )
 
PrintN("Press ENTER to exit"):Input()
End ; Close down and let PureBasic delete the Console and all variables.
EndIf

[edit] Python

Works with: Python version 2.5

width = int(raw_input("Width of myarray: "))
height = int(raw_input("Height of Array: "))
myarray = [[0] * width for i in xrange(height)]
myarray[0][0] = 3.5
print myarray[0][0]

Note: Some people may instinctively try to write myarray as [[0] * width] * height, but the * operator creates n references to [[0] * width]

You can also use a two element tuple to index a dictionary like so:

myarray = dict(((w,h), 0) for w in range(width) for h in range(height))
# or, in Python 3: myarray = {(w,h): 0 for w in range(width) for h in range(height)}
myarray[(0,0)] = 3.5
print myarray[(0,0)]

[edit] R

Translation of: C

input <- readline("Enter two integers.  Space delimited, please:  ")
dims <- as.numeric(strsplit(input, " ")[[1]])
arr <- array(dim=dims)
ii <- ceiling(dims[1]/2)
jj <- ceiling(dims[2]/2)
arr[ii, jj] <- sum(dims)
cat("array[", ii, ",", jj, "] is ", arr[ii, jj], "\n", sep="")

[edit] Ruby

puts 'Enter width and height: '
w=gets.to_i
arr = Array.new(gets.to_i){Array.new(w)}
arr[1][3] = 5
p arr[1][3]

[edit] Scala

object Array2D{
def main(args: Array[String]): Unit = {
val x = Console.readInt
val y = Console.readInt
 
val a=Array.fill(x, y)(0)
a(0)(0)=42
println("The number at (0, 0) is "+a(0)(0))
}
}

[edit] Smalltalk

Works with: GNU Smalltalk

Smalltalk has no problems in creating objects at runtime. I haven't found a class for multidimensional array in the standard library, so let us suppose to have a class named MultidimensionalArray.

|num1 num2 arr|
num1 := stdin nextLine asInteger.
num2 := stdin nextLine asInteger.
 
arr := MultidimensionalArray new: { num1. num2 }.
 
1 to: num1 do: [ :i |
1 to: num2 do: [ :j |
arr at: { i. j } put: (i*j)
]
].
 
1 to: num1 do: [ :i |
1 to: num2 do: [ :j |
(arr at: {i. j}) displayNl
]
].

A possible implementation for a BidimensionalArray class is the following (changing Multi into Bi and using this class, the previous code runs fine):

Object subclass: BidimensionalArray [
|biArr|
<comment: 'bidim array'>
].
BidimensionalArray class extend [
new: biDim [ |r|
r := super new.
r init: biDim.
^ r
]
].
BidimensionalArray extend [
init: biDim [
biArr := Array new: (biDim at: 1).
1 to: (biDim at: 1) do: [ :i |
biArr at: i put: (Array new: (biDim at: 2))
].
^ self
]
at: biDim [
^ (biArr at: (biDim at: 1)) at: (biDim at: 2)
]
at: biDim put: val [
^ (biArr at: (biDim at: 1)) at: (biDim at: 2) put: val
]
].

Instead of implementing such a class (or the MultidimensionalArray one), we can use a LookupTable class, using Array objects as keys (each element of the array will be an index for a specific dimension of the "array"). The final effect is the same as using an array (almost in the AWK sense) and the approach has some advantages.

|num1 num2 pseudoArr|
num1 := stdin nextLine asInteger.
num2 := stdin nextLine asInteger.
 
"we can 'suggest' an initial value for the number
of ''slot'' the table can hold; anyway, if we use
more than these, the table automatically grows"

pseudoArr := LookupTable new: (num1 * num2).
 
1 to: num1 do: [ :i |
1 to: num2 do: [ :j |
pseudoArr at: {i. j} put: (i * j).
]
].
 
1 to: num1 do: [ :i |
1 to: num2 do: [ :j |
(pseudoArr at: {i. j}) displayNl.
]
].

[edit] SNOBOL4

Works with: Macro Spitbol Works with: Snobol4+ Works with: CSnobol

Note: trim(input) is needed for Snobol4+.

*       # Get user X,Y dimensions
output = 'Enter X,Y:'; xy = trim(input)
xy break(',') . x ',' rem . y
 
* # Define and create array, 1-based
arr = array(x ',' y) ;* Or arr = array(xy)
 
* # Display array prototype
output = 'Prototype: ' prototype(arr)
 
* # Assign elements, angle or square brackets
* # Same array can hold ints, strings, etc.
arr<x,y> = 99; arr[1,1] = 'dog'
 
* # Display elements
output = 'arr[' xy '] = ' arr[x,y]
output = 'arr[1,1] = ' arr[1,1]
 
* # Release array for garbage collection
arr =
end

Output:

Enter X,Y:
5,5
Prototype: 5,5
arr[5,5] = 99
arr[1,1] = dog

[edit] Standard ML

val nbr1 = valOf (TextIO.scanStream (Int.scan StringCvt.DEC) TextIO.stdIn);
val nbr2 = valOf (TextIO.scanStream (Int.scan StringCvt.DEC) TextIO.stdIn);
val array = Array2.array (nbr1, nbr2, 0.0);
Array2.update (array, 0, 0, 3.5);
print (Real.toString (Array2.sub (array, 0, 0)) ^ "\n");

[edit] Tcl

Works with: Tcl version 8.5

package require Tcl 8.5
 
puts "enter X dimension:"
set dim2 [gets stdin]
puts "enter Y dimension:"
set dim1 [gets stdin]
# Make the "array"; we'll keep it in row-major form
set l [lrepeat $dim1 [lrepeat $dim2 {}]]
# Select a point at around the middle of the "array"
set y [expr {$dim1>>1}]
set x [expr {$dim2>>1}]
# Set the value at that point
lset l $y $x aValue
# Read the value at that point
puts [lindex $l $y $x]
# Delete the "array"
unset l

[edit] Toka

Toka has no direct support for 2D arrays, but they can be created and operated on in a manner similar to normal arrays using the following functions.

[ ( x y -- address )
cells malloc >r
dup cells >r
[ r> r> r> 2dup >r >r swap malloc swap i swap array.put >r ] iterate
r> r> nip
] is 2D-array
 
[ ( a b address -- value )
array.get array.get
] is 2D-get-element
 
[ ( value a b address -- )
array.get array.put
] is 2D-put-element

And a short test:

5 5 2D-array >r             #! Create an array and save the pointer to it
10 2 3 r@ 2D-put-element #! Set element 2,3 to 10
2 3 r@ 2D-get-element #! Get the element at 2,3
r> drop #! Discard the pointer to the array
Personal tools
Support