プログラム言語 配列

配列の基底クラス


int[][] array = new int[][]{
  new int[]{},
  new int[]{1},
  new int[]{2,3}
};

object o = array;
配列を含む全ての型はobjectを継承しているので格納可能

int i = ((int[][])o)[2][1];
// i : 3
int[][] array = new int[][]{{},{1},{2,3}};

Object o = array;
配列を含む全ての型はobjectを継承しているので格納可能

int i = ((int[][])o)[2][1];
// i : 3

配列の操作


文字列→配列変換 / 文字列←配列変換

string samplestr = "1,2,3,4,5";
string[] ary = samplestr1.Split(new char[] {','});
myAray[1] : "2"

string samplestr = @"aaaa@@bbb,,@@cc dddd,eee f";
string[] ary = samplestr.Split(
 separator: new string[]{ ",", " ", "@@" },
 options: StringSplitOptions.RemoveEmptyEntries);
 
string[] ary = samplestr.Split(
 separator: new string[] { ",", " ", "@@" },
 options: StringSplitOptions.None);
 
文字列でなく、文字で分割する場合 
string[] ary = samplestr.Split(
 separator: new [] { ',', ' ', '@' },
 options: StringSplitOptions.~);

Dim samplestr As String = "1,2,3,4,5"
Dim myAray() As String = samplestr.Split(",")
'myAray(1):2
Dim ReturnValue() As String

' "," を区切りとして分ける
ReturnValue() = Split("文字列1,文字列2,文字列3", ",")

ReturnValue(0) = "文字列1"
ReturnValue(1) = "文字列2"
ReturnValue(2) = "文字列3"

var Text = "A,B,C"
var Elm = Text.split(",");
⇒ Elm[0] : "A"
⇒ Elm[1] : "B"
⇒ Elm[2] : "C"
文字列→配列
$ary = explode(',', 'aaa,bbb,ccc,ddd');
$ary[2]:ccc

配列→文字列
$list = [1, 3, 5];
print( implode('_', $list) );
→1_3_5

$list = [
 '1' => 'A1',
 '3' => 'A3',
 '5' => 'A5',
];
print( implode('_', $list) );
→A1_A3_A5
キーではなく、値が連結される

split
指定の文字列を、指定の文字で分割して配列に格納する

#指定の文字列(分割対象)
my $str= "a/b/c/d/e";

#指定の文字で分割する場合
my @ary = split('/' , $str);

#正規表現リテラルで分割する場合
my @ary = split(/\// , $str);
#「/」を引数で指定する場合は「\」を付ける(エスケープ)
#my @ary = split(/// , $str); はダメ

#指定数のみ要素に分割する。残りは単一の要素
my @ary = split('/' , $str, 3);
⇒ $ary[0] : a
⇒ $ary[1] : b
⇒ $ary[2] : c/d/e


qw演算子
「 (スペース)」で区切られた文字を配列に格納する
my @ary = qw( 1 2 3 );
⇒ @ary = (1,2,3);と同じ
区切り文字(デミリタ)にはどんな文字でも使用可「qw//」、「wq{}」、「qw[]」、「qw<>」他
my @ary = qw/ 1 2 3 /;
my @ary = qw{ 1 2 3 };
my @ary = qw[ 1 2 3 ];
my @ary = qw< 1 2 3 >;


join
※配列を結合する
my @ary = (1,2,3);
my @str = join('-' , @ary);
⇒ @str : 1-2-3

メールアドレスにおいて、ローカルパートとドメイン名を「@」で結合する
(配列でなく第二・第三引数に文字列を渡すやり方も可)
my $local = "aaa";
my $domain = "test.com";
my $adress = join("@" , $local , $domain);
⇒ aaa@test.com

#改行を挟む
my $str = join('\n' , @str);


配列のコピー

clone()
配列から配列へ全要素をコピー
配列同士の要素数は異なっていてもOK

int[] before = new int[]{5,5,5};
int[] after = before.clone();
⇒after {5,5,5}


System.arraycopy()
配列から配列へ指定の要素をコピー
配列同士の要素数は同じ

int[] before = new int[]{5,5,5};
int[] after = new int[3];

//System.arraycopy(src, srcPos, dest, destPos, length)
System.arraycopy(before, 1, after, 1, 2);
before {5,5,5}
index:1から2文字をコピー↓

after {0,0,0}
index:1から2文字へコピー↓

after {0,5,5}

'配列コピー
Dim Before() As Integer
Dim After() As Integer

For elmCnt = 0 To UBound(Before) – 1
  After(elmCnt) = Before(elmCnt)
Next elmCnt

Variant型の配列であれば
After = Before
も可。
しかし遅い。
リストのコピー」参照

サブルーチンへの配列渡し

配列→配列
int ary[] = { 1, 2, 3, 4, 5 };

int ret = fnPlus(ary);
ret:15


int fnPlus(int p[])
{
 int sum = 0;
 for (int i = 0; i < 5; i++)
 {
  sum += p[i];
 }
 return sum;
}


配列→ポインタ
int ret = fnPlus(ary);
ret:15

int fnPlus(int *p)
{
 配列の先頭アドレスを取得
 p = &ary[0];

 
 int sum = 0;
 for (int i = 0; i < 5; i++)
 {
  sum += p[i];
 }
 return sum;
}


ポインターによる配列操作

通常配列
int array[5] = { 1, 2, 3, 4, 5 };
arrayに配列の先頭アドレスを格納

int ret;
ret = array[0];
ret = *array;
ret:1

ret = array[1];
ret = *(array + 1);
ret:2

ret = fnPlus(array, 5);
ret:15
ret = fnPlus(&array[0], 5);
配列の先頭アドレスを渡す
ret:15


メモリ領域の動的確保
ポインタ変数:pに配列の先頭アドレスを格納

int *p = new int[5]{ 1, 2, 3, 4, 5 };

ret = *(p + 1);
ret:2
ret = *(p + 2);
ret:3

ret = fnPlus(p, 5);
ret:15

delete p;


int fnPlus(int *p, int elmCnt)
{
 int sum = 0;
 for (int i = 0; i < elmCnt; i++)
 {
  sum += *(p + i);
 }
 return sum;
}

要素の操作


初期化・要素指定

int[] myInt = {1,2};
myInt[0] = 1;
myInt[1] = 2;
myInt[2] = 3; ⇒エラー

var x1 = myInt.First();
var x2 = myInt.Last();
var x3 = myInt.Min();
var x4 = myInt.Max();
var x5 = myInt.Count();
※配列は各IEnumerable拡張メソッドを使用可能
プログラム言語 LINQ.Enumerable」参照


型推論を用いた配列
var ary = new[] { 1, 2, 3, 4, 5 };

var ary = new[]
{
 new[] { 1,2,3 },
 new[] { 1 },
 new[] { 1,2 }
};

匿名クラスを用いた配列
var ary = new[]
{
 new { x = 1, y = 1 },
 new { x = 2, y = 1 },
 new { x = 3, y = 1 }
};

int myArray1[] = { 1, 2, 3};
// myArray[0]:1
// myArray[1]:2
// myArray[2]:3

// int myArray[3] = { 1, 2, 3, 4 };
// エラー

int myArray2[3] = { 1, 2 };
// myArray[0]:1
// myArray[1]:2
// myArray[2]:0

for each (int var in myArray2)
{
  Console::WriteLine(var);
  // → 1 2 0
};

// 配列全体のバイト数
int size = sizeof(myArray2);
// 12

// 要素のバイト数
int size = sizeof(myArray2[0]);
// 4

// 要素数
int size = sizeof(myArray2) / sizeof(myArray2[0]);
// 3


マクロを使用
wchar_t myChar1[] = L"VisualC++";
wchar_t *myChar2 = L"VisualC#";

int elmCnt;
elmCnt = _countof(myChar1);
→10
終端文字(\0)を含んだ要素数


elmCnt = _countof(myChar2);
コンパイルエラー
配列しか引数に指定できない。


Dim myInt() As Integer = {1, 2}
myInt(0) = 1
myInt(1) = 2
myInt(2) = 3 ⇒エラー

Dim x1 As Integer = myInt.First()
Dim x2 As Integer = myInt.Last()
Dim x3 As Integer = myInt.Max()
Dim x4 As Integer = myInt.Min()
Dim x5 As Integer = myInt.Count()
Dim MyArray(3) As String
Dim MyArray(2 To 5) As String

MyArray(0) = "A"
MyArray(1) = "B"
MyArray(2) = "C"
MyArray(3) = "D" ←エラー


Dim myAry() As Integer
Dim elmCnt As Integer

elmCnt = UBound(myAry)
'実行時エラー

ReDim myAry(0)
elmCnt = UBound(myAry)
elmCnt:0


Dim myAry() As Variant
Dim elmCnt As Integer

myAry() = Array(1, 2, 3, 4, 5)
elmCnt = UBound(myAry)
elmCnt:4
int[] array = new int[3];
array[0] = 5;
array[1] = 5;
array[2] = 5;
array[3] = 5; ⇒ 実行時エラー

int array[] = new int[3]; も可

宣言と同時に要素を設定
int array[] = new int[]{5,5,5};
int array[] = {5,5,5};
//方法①
var strTest = new Array(3);

strTest[0] = 'test1';
strTest[1] = 'test2';
strTest[2] = 'test3';


//方法②
var strTest = new Array('test1', 'test2', 'test3');
要素指定追加
$ary[0] = '1番目要素';
$ary[1] = '2番目要素';
$ary[2] = '3番目要素';

range()関数利用
$ary = [1, 2, 3];  → 1, 2, 3
$ary = array(1, 2, 3);
$ary = range(1, 5);  → 1, 2, 3, 4, 5
$ary = range(1, 10, 2);  → 1, 3, 5, 7, 9
$ary = range('a', 'f');  → 'a', 'b', 'c', 'd', 'e', 'f'
$ary = array_fill(0, 3, 'foo');  → "foo", "foo", "foo"
$ary = array_pad(array(), 3, 'foo');  → "foo", "foo", "foo"

配列判定
if (is_array($ary)) echo '配列です';

用素数
$cnt = count($ary);

ary = (1,2,3)
print(ary) #(1,2,3)
print(ary[0]) #1

文字列を配列と見なす
s = 'ABCD'[0]
A
※変数に「@」を付ける。arrayの「a」

@x[0] = 1;
@x[1] = 'aaa';

print "@[1]\n";
⇒aaa

@x = (1, 'two');
@x[2] = '3′;
@x[3..4] = ('four', 'five');

print "@x\n";
print "@x[1..3]\n";
⇒1 two 3 four five
⇒two 3 four


最大Index値、要素数

#」を付ける
my @ary = (1,2,3);
my $cnt = $#ary;
⇒2 (Index値)

何も付けない
my @ary = (1,2,3);
my $cnt = @ary;
⇒3 (要素数)

scalar」を付ける
my @ary = (1,2,3);
my $cnt = scalar @x
⇒3 (要素数)


配列的代入
( $year, $month, $day) = (1978, 8, 4);
print $year\n";
print $month\n";
print $day\n";
⇒1978
⇒8
⇒4

並び替え(自然順序)

自然順序:数字、アルファベット順等
public static void main(String[] args) {
 Integer[] ary1 = {3, 1, 2};
 Arrays.sort(ary1);
 →1 2 3

 Object[] ary2 = { new String("aa"), new Integer(1), "5", 0};
 Arrays.sort(ary2); →実行時エラー
}

ary = (2, 5, 3.14, 1, -7)

#昇順
ary.sort()
print(ary)
# (-7, 1, 2, 3.14, 5)

#ASCIIコード(大文字が先)昇順
ary = ('elephant', 'Dog', 'cat')
ary.sort()
print(ary)
# ('Dog', 'cat', 'elephant')

#ASCIIコード(大文字が先)降順
ary.sort(reverse=True)
print(ary)
# ('elephant', 'cat', 'Dog')

#アルファベット昇順(要素を全て小文字とみなす)
ary.sort(key=str.lower)
print(ary)
# ('cat', 'Dog', 'elephant')

ary = (2, 5, 3.14, 1, -7, 'elephant', 'Dog', 'cat')
ary.sort()
# エラー

要素数変更

using System.Collections;

int[] ary = { 1, 2, 3 };
Array.Resize(array: ref ary, newSize: 5);
参照渡しで配列を渡す。(「プログラム言語 変数/値渡し・参照渡し」参照)

ary[3] = 4;
ary[4] = 5;
ary[5] = 6; ⇒ エラー


配列⇒リスト変換
ArrayList list = new ArrayList(ary);

list.Add(value: 6);

リスト⇒配列変換
ary = (int[])list.ToArray(typeof(int));
ary[5] += 1;
ary[5] : 7


ラムダ式を利用した配列の初期化(再配置)については「ラムダ式/配列の初期化」参照

Imports System.Collections
Dim ary() As Integer = {1, 2, 3}

Array.Resize(array:=ary, newSize:=5)

ary(3) = 4
ary(4) = 5
ary(5) = 6 ⇒エラー

‘ 配列⇒リスト変換
Dim list As New ArrayList(ary)

list.Add(6)

‘ リスト⇒配列変換
ary = DirectCast(list.ToArray(GetType(Integer)), Integer())
要素数無しで定義
Dim MyArray() As String
Dim MyArray(3) As String

要素数定義
Redim MyArray(3)
MyArray(0) = "A"
MyArray(1) = "B"
MyArray(2) = "C"
MyArray(3) = "D" ←エラー

既存要素を維持したままで新要素を追加
Redim Preserve MyArray(4)
MyArray(3) = "D" ←OK

Redim MyArray(4)だと全要素が初期化される
要素自動追加
$list[0] = '1番目要素';
$list[] = '2番目要素';
$list[] = '3番目要素';

指定要素削除
unset($list['3']);
unset($list[3]);

$listの末尾に追加
array_push($list, 4);
$list[] = 4 の方が速い

$listの末尾から要素を1つ削除
array_pop($list);

$listの先頭から要素を1つ削除
array_shift($list);

$listの先頭に追加
array_unshift($list, 4);

先頭に追加
var ary1[];
ary1.unshift('a');
ary1.unshift('b');
ary1.unshift('c');
→['c', 'b', 'a']

末尾に追加
var ary2[];
ary2.push('1');
ary2.push('2');
ary2.push('3');
→['1', '2', '3']

連結

連結方法重複時の挙動
+第一配列優先
array_merge()第二配列優先
array_merge_recursive()両方優先

【「+」による一般配列連結】 $list1 = [1, 3, 5];
Array(
  [0] => 1
  [1] => 3
  [2] => 5
)

$list2 = [1, 2, 3,4];
Array(
  [0] => 1
  [1] => 2
  [2] => 3
  [3] => 4
)

$list3 = $list1 + $list2;
Array(
  [0] => 1
  [1] => 3
  [2] => 5
  [3] => 4
)
第一配列に無い要素が追加追加される


【「+」による連想配列連結】 $list1 = [
 'A1' => 'A1',
 'A3' => 'A3',
 'A5' => 'A5',
];
$list2 = [
 'A1' => 'A1',
 'A2' => 'A2',
 'A3' => 'A3',
];

$list3 = $list1 + $list2;
Array(
  [A1] => A1
  [A3] => A3
  [A5] => A5
  [A2] => A2
)
第一配列に無い要素が追加される


【「array_merge」による通常配列連結】 $list1 = [1, 3, 5];
Array(
  [0] => 1
  [1] => 3
  [2] => 5
)

$list2 = [1, 2, 3,4];
Array(
  [0] => 1
  [1] => 2
  [2] => 3
  [3] => 4
)

$list3 = array_merge($list1, $list2);
Array(
  [0] => 1
  [1] => 3
  [2] => 5
  [3] => 1
  [4] => 2
  [5] => 3
  [6] => 4
)
インデックス番号が重複する場合は後ろに追加される
第一配列に無い要素も追加される


【「array_merge」による連想配列連結】 $list1 = [
 'A1' => 'A1-1',
 'A3' => 'A3-1',
 'A5' => 'A5-1',
];

$list2 = [
 'A1' => 'A1-2',
 'A2' => 'A2-2',
 'A3' => 'A3-2',
];

$list3 = array_merge($list1, $list2);
Array(
  [A1] => A1-2
  [A3] => A3-2
  [A5] => A5-1
  [A2] => A2-2
)
キーが重複する場合は第二配列が優先される
第一配列に無い要素も追加される


【「array_merge_recursive」による連想配列連結】 $list1 = [
 'A1' => 'A1-1',
 'A3' => 'A3-1',
 'A5' => 'A5-1',
];

$list2 = [
 'A1' => 'A1-2',
 'A2' => 'A2-2',
 'A3' => 'A3-2',
];

$list3 = array_merge_recursive($list1, $list2);
Array(
  [A1] => Array
    (
      [0] => A1-1
      [1] => A1-2
    )
  [A3] => Array
    (
      [0] => A3-1
      [1] => A3-2
    )
  [A5] => A5-1
  [A2] => A2-2
)
キーが重複した場合、子配列が生成される

タプルはイミュータブル(更新不可)
リスト化&追加&タプル化は可能
var ary1 = ['c', 'b', 'a'];
var ary2 = ['1', '2', '3'];
末尾に結合
var ary3 = ary1.concat(ary2);
→['c', 'b', 'a', '1', '2', '3']

置換

array_splice(操作対象配列, 操作開始位置, 置換要素数, 置換対象配列)

$list = [
 'A',
 'B',
 'C',
];
array_splice($list, 0, 2, ['D1', 'D2', 'D3']);
$listの1番目の要素から2要素を['D1', 'D2', 'D3']で置換

$list = [
 'D1',
 'D2',
 'D3',
 'B',
 'C',
];


$list = [
 'A',
 'B',
 'C',
];
array_splice($list, -2, 2, ['D1', 'D2', 'D3']);
$listの2番目(-2)の要素から2要素を['D1', 'D2', 'D3']で置換

$list = [
 'A',
 'D1',
 'D2',
 'D3',
];

切り取り

$list1 = ['A', 'B', 'C'];
Array(
  [0] => A
  [1] => B
  [2] => C
)
$list2 = array_slice($list1, 1, 2, false);

Array(
  [0] => B
  [1] => C
)
元のインデックス番号は維持されない
インデックス番号が0から降り直される

$list1 = ['A', 'B', 'C'];
Array(
  [0] => A
  [1] => B
  [2] => C
)
$list2 = array_slice($list1, 1, 2, true);

Array(
  [1] => B
  [2] => C
)
元のインデックス番号は維持される

タプルはイミュータブル(更新不可)
リスト化&追加&タプル化は可能

検索

$list = [
 'PHP',
 'Java',
 'JavaScript',
 'PHP',
];

$ret = array_search('Java', $list);
→1
先頭の要素番号が取得される
$ret = array_search('C#', $list);
→false

制御文で使用する場合
if (array_search('Java', $list)===false){
 
}


$list = [
 'PHP',
 'Java',
 'JavaScript',
 'PHP',
];
$ret = in_array('Java', $list);
→true
$ret = in_array('Ruby', $list);
→false

制御文で使用する場合
if (in_array('Java', $list)){
 
}

ary = ('elephant', 'dog', 'cat')

インデックス番号(0から)
print(ary.index('elephant')) # 0

ret = 'cat' in ary
print(ret)
# True

ret = 'bird' in ary
print(ret)
# False

ret = 'cat' not in ary
print(ret)
# False

ret = 'bird' not in ary
print(ret)
# True

# 要素番号
index = ary.index('cat')
print(index)
# 2

index = ary.index('elephant')
print(index)
# 0

index = ary.index('bird')
print(index)
# エラー

特殊な配列


多次元配列

int[,] ary = new int[2, 2];
ary[0, 0] = 1;
ary[0, 1] = 2;
ary[1, 0] = 3;
ary[1, 1] = 4;

int[,] ary = new int[,]
{
  { 1, 2 },
  { 3, 4 }
};

foreach (int elm in ary)
{
  Console.WriteLine(elm);
}
int[][] ary = new int[][]{1,2,3,4}
int[][] ary = {1,2,3,4}
int ary[][] = {1,2,3,4}

C#における、int[,] ary ~ の構文は無い。
(多次元配列とジャグ配列の宣言の違い無し)
通常
ary = ((1,2,3), (4,5,6))
print(ary)
# ((1 2 3) (4 5 6))

2つ目の配列の1つ目の要素を指定
print(ary[1][0]) #4
タプルでもインデックスの指定は[]を用いる

ジャグ配列

要素が配列である配列
配列の要素として配列を格納する為には配列インスタンスを作成する必要がある。

int[][] ary = new int[3][];
ary[0] = new int[] { 1, 2, 3 };
ary[1] = new int[] { 1, 2 };
ary[2] = new int[] { 1, 2, 3, 4, 5 };

int[][] ary = new int[3][]
{
  new int[] { 1, 2, 3 },
  new int[] { 1, 2 },
  new int[] { 1, 2, 3, 4, 5 }
};

foreach (int[] elms in ary)
{
  foreach (int elm in elms)
  {
    Console.WriteLine(elms);
  }
}
配列の要素として配列を格納する為に、配列インスタンスを作成する必要無し(自動)

int[][] array = new int[2][2];
array[0][0] = 5;
array[0][1] = 5;
array[1][0] = 5;
array[1][1] = 5;
array[2][0] = 5; ⇒ 実行時エラー

宣言と同時に要素を設定
int[][] array = new int[][]
{
  {5,5},
  {5,5}
};

2次元目の要素数を定めずに宣言
int[][] array = new int[2][];
array[0] = new int[]{5,5};
array[1] = new int[]{5,5,5};
array[2] = new int[]{5,5,5,5}; ⇒ 実行時エラー
my @elm1 = ("row1-col1", "row1-col2", "row1-col3");
my @elm2 = ("row2-col1", "row2-col2", "row2-col3");
my @table = (@elm1, @elm2);
print $table[0][0] #エラー

#配列のリファレンス取得
my $ref1 = ["row1-col1", "row1-col2", "row1-col3"];
my $ref2 = ["row2-col1", "row2-col2", "row2-col3"];
my @table = ($ref1, $ref2);
print $table[0][0] # ⇒ "row1-col1"


#連想配列の中に配列を入れる

my $elm1 = {
 name => 'yone',
 age => 36,
};
my @family = ('wife', 'child1', 'child2');
my $elm2 = {
 #配列を作成と同時にのリファレンスを格納
 food => ['niku', 'sushi'],
 sports => 'basket',
 #配列のリファレンスを格納
 family => \\@family,
};
my %table = (
 elm1 => $elm1,
 elm2 => $elm2
);

print Dumper %table,"\\n";


$VAR1 = 'elm2';
$VAR2 = {
 'sports' => 'basket',
 'family' => [
  'wife',
  'child1',
  'child2'
   ],
 'food' => [
   'niku',
   'sushi'
  ]
};
$VAR3 = 'elm1';
$VAR4 = {
 'name' => 'yone',
 'age' => 36
};



ポインタ(リファレンス/デリファレンス)を使用した配列の利用については「プログラム言語 ポインタ / 配列のポインタ」参照

株式会社米良太事務所の最新情報をお届けします

1週間でできる会員サイト「Limited」

1週間でできる会員サイト「Limited」
必要最小限。だから分かりやすい。始めやすい。続けやすい。
限定① 安⼼・安全の会員制
限定② 必要最⼩限の機能
限定③ 独⾃機能を追加可能