はじめに
配列の最後の要素にアクセスする際はMatlabの予約語end
を使うのが簡単。
matlab
a = [0, 1, 2, 3, 4];
a(end)
% ans = 4
a(1:end-1)
% ans = 0 1 2 3
ただしこのend
を変数に代入することはできない。
pythonだと負数のインデックスがあるので、変数を使った最後の要素へのアクセスが容易。
pyhon
a = [0, 1, 2, 3, 4]
a[-1]
# 4
a[0:-1]
# 0 1 2 3
b = -1
a[b]
# 4
a[0:b]
# 0 1 2 3
やりたいこと
そんなに使う場面が多いわけではないが、Matlabでも配列の最後の要素に変数を使ってアクセスできるようにしたい。
可能な限りend
を使わず、同じぐらいの手軽さでやりたい。
ネック
変数にend
やそれを含むものを代入できない。
matlab
a = [0, 1, 2, 3, 4];
% 以下いずれもエラーが出る
b = end;
c = end-1;
end
とは?
この記載の通り、
- コードブロックの終了
- 最後の配列インデックス
の二つの役割があるMatlab言語の基本的な予約語
1.の使い方
matlab
flag = true;
if flag == true
myfunc(1)
else
myfunc(2)
end
function output = myfunc(input)
output = 2*input;
end
ここで使われるend
はどちらもコードブロックの終了を表す。
2.の使い方
matlab
a = [0, 1, 2, 3, 4];
a(end)
% ans = 4
a(1:end-1)
% ans = 0 1 2 3
冒頭の使い方がこちら。
つまり、一つの予約語に複数の役割があり、それぞれ使い方が全く異なっている。
コードブロックの終了は変数化の必要な状況がない(と思われる)が、配列インデックスは変数化することがよくあるため、最後の要素およびそれを含むインデックスも変数化したい。
end
を使わず配列の最後にアクセスする方法
①配列サイズを取得する関数(size,numel,length)を使う
matlab
a = [0, 1, 2, 3, 4];
[~,b] = size(a); % ベクトルおよび2次元配列に対するsize()の出力は[行数,列数]
% 列ベクトルの場合は[b,~] = size(a);
a(b)
% ans = 4
c = numel(a); % numel()の出力は要素数
a(1:c-1)
% ans = 0 1 2 3
d = length(a); % length()の出力は、最大の配列の次元の長さ。今回は2次元目(列)の長さ。
a(d-2:d)
% ans = 2 3 4
配列がベクトル(2次元配列で、一方の次元長さが1)の場合はこれらで事足りる。
2次元以上の配列でそれぞれの次元の最後の要素にアクセスする場合はsize()
を使う。
matlab
a = [0, 1, 2, 3, 4,
5, 6, 7, 8, 9,
10,11,12,13,14];
[r,c] = size(a)
% r = 3 c = 5
a(r,c)
% ans = 14
a(r-2,c-4)
% ans = 0
②ループ処理を使う
matlab
array = [1, 2, 3, 4, 5]; % 例としての配列
i = 1;
while true
try
temp = array(i);
i = i + 1;
catch
lastIndex = i - 1;
break;
end
end
array(lastIndex)
% ans = 5
③配列の範囲を使う
matlab
array = [1, 2, 3, 4, 5]; % 例としての配列
array_ones = ones(size(array)); % find()は非ゼロ要素のインデックスを返すため、最後がゼロだった場合に備えた処理
indices = 1:max(1, find(array_ones, 1, 'last'));
indices_lr = fliplr(indices); % この配列の最後の要素がarrayの最後のインデックスになるが、endを使わないように左右反転
lastIndex = indices_lr(1); % 左右反転したのでindices(end)と同じ
array(lastIndex)
% ans = 5
結論
end
ほど簡単に最後の要素にアクセスする方法は調べた限り存在しない。
size()
やnumel()
を使うのが無難かな。
他に簡単な方法があれば是非教えてください。
内容およびコードの一部にchatGPTを使用しています。