配列

D 言語の配列はいろいろと拡張されていてかなり高機能である.

静的配列

int[3] a;

コンパイル時に大きさが決定される配列

D 言語は, 変数名の前に “[n]” を書く前置配列宣言形式を推奨, ポインタ型の ときに C よりわかりやすいため.

後置配列宣言形式は C と同じ形式

int a[3]; // 推奨されていない

動的配列

int[] a;

実行時にサイズを変化させられる配列である.

dyna_array.d

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import std.stdio;

void main(){

  int[] a; // 動的配列
  a ~= 5;
  a ~= 6;
  a ~= 7;
  a ~= 8;
/*
  動的配列は "~=" で末尾に要素を追加できる.
*/

  foreach (int i; a)
    writefln("a[%d] = %d", i, i);

  writeln("Other method to use array elements:");
  
  a.length = 2;
/*
  D の配列はプロパティを持つ.
  .length プロパティを書き換えて配列のサイズを変更できる.
*/
  foreach(int i; a)
    writefln("a[%d] = %d", i, i);
}

dyna_array.d の実行結果は:

[cactus:~/code_d/d_tuts]% ./dyna_array
a[5] = 5
a[6] = 6
a[7] = 7
a[8] = 8
Other method to use array elements:
a[5] = 5
a[6] = 6

連想配列

associative_array.d

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import std.stdio;
import std.string;

void main(){
  write("?> ");
  
  int[string] a;
/*
  D 言語では配列のインデックスに整数以外も使える.
  文字列をインデックスにするときは int[string] と書く.
*/
  
  a["red"] = 0;
  a["yellow"] = 1;
  a["green"] = 2;

  char[] line = readln().dup;
  line = chomp(line.idup).dup;
  
  writeln(a[line]);
}

associative_array.d の実行結果は:

[cactus:~/code_d/d_tuts]% ./associative_array
?> red
0
[cactus:~/code_d/d_tuts]% ./associative_array
?> yellow
1
[cactus:~/code_d/d_tuts]% ./associative_array
?> green
2

associative_array2.d

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import std.stdio;

void main(){

  int[string] a;
  
  a["signal"] = 123;
  int* p;
  p = "signal" in a;
/*
  連想配列が任意の key に対応する value を持っているかどうかは in で調べられる.
  in 式は, 連想配列が任意の key に対応する value を持っていればその要素へのポインタを
  そうでなければ null を返す.
*/
  if(p != null){
    writeln(*p);
  }
}

associative_array2.d の実行結果は:

[cactus:~/code_d/d_tuts]% ./associative_array2
123

配列のプロパティ

proper_array.d

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import std.stdio;

void main(){
  int a;
  int b = 3;

  int[10] c;

  writefln("int.init = %d", int.init);
  writefln("a.init = %d", a.init);
  writefln("b.init = %d", b.init);
/*
  D 言語の型は .init プロパティの値を初期値として持っている.
*/

  writefln("c.length = %d", c.length);
/*
  配列の要素数は .length で取得できる.
*/
}

proper_array.d の実行結果は:

[cactus:~/code_d/d_tuts]% ./proper_array
int.init = 0
a.init = 0
b.init = 0
c.length = 10

sort_array.d

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import std.stdio;

void main(){
  int[5] a;
  a[0] = 3;
  a[1] = 5;
  a[2] = 10;
  a[3] = 1;
  a[4] = 2;
  
  foreach(int i; a)
    writef("%d ", i);
  writeln();
  
  a.sort;
  
  foreach(int i; a)
    writef("%d ", i);
  writeln();
}

sort_array.d の実行結果は:

[cactus:~/code_d/d_tuts]% ./sort_array
3 5 10 1 2
1 2 3 5 10

配列リテラル

literal_array.d

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import std.stdio;

void f(int[] x){
  foreach(i; x)
    write(i);
  writeln();
}

int[] g(){
  return [4, 5, 6];
/*
  配列を [~] の形でハードコーディングできる.
  [] の要素の共通の型が, 配列リテラルのすべての要素の型として扱われる.
  [-1, 2.0, 3u] は double[] 型.
  関数の書き方あだいたい C と同じ.
  配列リテラルを関数から返せる.
*/
}

void main(){
  f( [1, 2, 3] );
  f( g() );
}

literal_array.d の実行結果は:

[cactus:~/code_d/d_tuts]% ./literal_array
123
456

連想配列リテラル

int[string] 型の連想配列は

literal_array_asso.d

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import std.stdio;

void main(){
  int[string] signal = ["red":1, "yellow":2, "green":3];
/*
  連想配列リテラルは [key:value, ...]
*/
  writefln( "signal[\"red\"]    = %d", signal["red"] );
  writefln( "signal[\"yellow\"] = %d", signal["yellow"] );
  writefln( "signal[\"green\"]  = %d", signal["green"] );
}

literal_array_asso.d の実行結果は:

[cactus:~/code_d/d_tuts]% ./literal_array_asso
signal["red"]    = 1
signal["yellow"] = 2
signal["green"]  = 3

配列の初期化

静的配列の初期化:

int[4] a = [0, 1, 2, 3];

動的配列の初期化:

int[] d = [0, 1, 2, 3];

連想配列の初期化:

int[string] asso = ["red":1, "yellow":2, "green":3];

スライシング

slice_array.d

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import std.stdio;

void main(){
  int[] a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  int[] b;

  b = a[3..8];
/*
  配列名[インデックス番号..要素の n 個目] ( n 個目は 1 から数える).
*/
  foreach(int i; b)
    write(i);
  writeln();

  b = a[2..$];
/*
  [...] の中では配列の要素数を表す $ が使用できる.
*/
  foreach(int i; b)
    write(i);
  writeln();
}

slice_array.d の実行結果は:

[cactus:~/code_d/d_tuts]% ./slice_array
34567
23456789

配列の一括コピー

copy_array.d

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import std.stdio;

void main(){
  int[3] a;
  int[3] b = [1, 2, 3];

  /* 四つとも同じ意味 */
  a = b;
  a[] = b;
  a[] = b[];
  a[0] = b[0], a[1] = b[1], a[2] = b[2];

  /* 二つとも同じ意味 */
  a[0..2] = b[1..3];
  a[0] = b[1], a[1] = b[2];
/*
  [0..2] は [インデックス..n個目]
*/

  foreach(int i; a)
    write(i);
  writeln();
}

/*
  a[0..2] = a[1..3] は範囲が重なる一括コピーはエラーになる.
*/

copy_array.d の実行結果は:

[cactus:~/code_d/d_tuts]% ./copy_array
233

配列への一括データセット

dataset_array.d

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import std.stdio;

void main(){
  int[3] a;
  int[3] b = [1, 2, 3];

  /* 四つとも同じ意味 */
  a = b;
  a[] = b;
  a[] = b[];
  a[0] = b[0], a[1] = b[1], a[2] = b[2];

  /* 二つとも同じ意味 */
  a[0..2] = b[1..3];
  a[0] = b[1], a[1] = b[2];
/*
  [0..2] は [インデックス..n個目]
*/

  foreach(int i; a)
    write(i);
  writeln();
}

/*
  a[0..2] = a[1..3] は範囲が重なる一括コピーはエラーになる.
*/

dataset_array.d の実行結果は:

[cactus:~/code_d/d_tuts]% ./dataset_array
333

配列演算

calc_array.d

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import std.stdio;

void main(){
  int[5] a, b, c, d, e, f;
  int[] x = [1, 2, 3, 4, 5];
  int[] temp;

  a[] = x[] + 10;
  b[] = x[] - 10;
  c[] = x[] * b[];
  d[] = x[] / 10;
  e[] = -x[];
  f[] = ~x[]; // logic not
  temp = f[2..$];

  writefln( "%3d", a );
  writefln( "%3d", b );
  writefln( "%3d", c );
  writefln( "%3d", d );
  writefln( "%3d", e );
  writefln( "%3d", f );
  writefln( "%3d", temp );
}

calc_array.d の実行結果は:

[cactus:~/code_d/d_tuts]% ./calc_array
[ 11,  12,  13,  14,  15]
[ -9,  -8,  -7,  -6,  -5]
[ -9, -16, -21, -24, -25]
[  0,   0,   0,   0,   0]
[ -1,  -2,  -3,  -4,  -5]
[ -2,  -3,  -4,  -5,  -6]
[ -4,  -5,  -6]