2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Matlab】endを使わず配列の最後の要素にアクセスする方法

Posted at

はじめに

配列の最後の要素にアクセスする際は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を使用しています。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?