LoginSignup
12
8

More than 5 years have passed since last update.

いろいろな言語で配列の最後の要素

Last updated at Posted at 2018-09-20

各種言語で配列(のようなもの)の最後の要素をとってくる方法を列挙しようと思う。

きっかけは、C++ の *std::rbegin(x)

x の最後の要素がほしいときにx と二度書かなければならない言語と1度で済む言語があるよなぁとか。

C言語

c
#define COUNTOF(x) (sizeof(x) / sizeof(*(x)))
void somefunc(){
  int x[] = { 1, 2, 3 };
  int last = x[COUNTOF(x)-1]
}

たぶん、これより面倒な言語あまりはないと思う。マクロまで定義して大変。

追いかけてないのでよく知らないんだけど、C11 だともっといい方法があったりするのだろうか。

C++ でも、C++14より前の場合、生の配列なら上記の方法を使うと思う。

※ 配列のサイズがゼロの場合は、そんな配列作れないので考慮する必要がない。

C++14 とそれ以降の C++

c++14
#include <iostream>
#include <vector>

void somefunc() {
  int x[] = { 1, 2, 3 };
  int last1 = *std::rbegin(x);
  std::vector<int> y{ 1, 2, 3 };
  int last2 = y.back();
}

std::rbegin() は、C++11 の標準じゃないと思うけど、C++14 に対応していないことになっている環境でも使えることも多いと思う。boost にも同様の関数がある。

※ 配列のサイズがゼロの場合は、そんな配列作れないので考慮する必要がない。
※ vector のサイズがゼロの場合は、未定義動作かな。

C#

C#
class SomeClass
{
    public void SomeMethod()
    {
        int[] x = new int[]{ 1, 2, 3 };
        int last1 = x[x.Length-1];
        int last2 = x.Last(); // using System.Linq; が必要
        List<int> y = new List<int>{ 1, 2, 3 };
        int last3 = y[y.Count-1];
        int last4 = y.Last(); // using System.Linq; が必要
    }
}

System.Linq を使うと .Last() を使うことができる。

※ 配列が空の場合は例外だと思う。

Go言語

go
x := []int{1, 2, 3}
last := x[len(x)-1] 

last とか back みたいなものはなくて、 len で長さをとってきて -1 するしかない。
と思う。

※ スライスのサイズがゼロの場合は、パニック。

groovy

x=[1,2,3]
last1 = x[-1]
last2 = x.last()

last メソッドがある。
メソッドなので括弧が必要。
負のインデックスも使える。

※ 配列が空の場合。

  • [-1]java.lang.ArrayIndexOutOfBoundsException
  • .last()java.util.NoSuchElementException

違う例外になるのが面白い。

JavaScript

JavaScript
var x=[1,2,3]
var last=x[x.length-1]

length はプロパティ。
最終要素のためのメソッドやプロパティはない。よね?

※ 配列が空の場合は、 undefined を返す。

Objective-C

Objective-C
#import <Foundation/Foundation.h>

void someFunc()
{
 NSArray * x = @[@1, @2, @3];
 NSObject * last = [x lastObject];
}

Objective-C はよく知らないんだけど、こんな感じだよね。
最後の要素をアクセスするためのメソッド lastObject がある。

※ 配列が空の場合は、nil を返す。

PHP

最後の要素をとる関数 end に副作用があるらしい。

see PHP – 配列の最後の要素の判定にend()は使わない方がいい話
see PHPで配列の最後の値を取得する

end を使うべきかどうかはケースバイケース。PHP 難しい。

python

python3
import numpy
x = [ 1, 2, 3 ]
last1 = x[-1]
y = numpy.asarray([1.0, 2.0, 3.0])
last2  = y[-1]

インデックスに負を与えると後ろから数える。
知っていれば簡単。

※ 配列が空の場合は IndexError: list index out of range が発生。例外かな。

R

R
x<-c(1,2,3)
last<-x[length(x)]

インデックスが 1オリジンなので、x[length(x)-1] ではない。

※ 配列が空の場合は NULL を返す

ruby

ruby2.5
x = [ 1, 2, 3 ]
last1 = x[-1]
last2 = x.last

負のインデックスも使えるけど、専用のメソッドもある。
私は [-1] よりも .last が好き。

※ 配列が空の場合は、いずれも nil を返す。

まとめ

言語 アクセス 配列が空の場合
C x[sizeof(x)/sizeof(*x)-1] 無理
C++14(配列) *std::rbegin(x) xが配列なら無理
C++(vector) x.back() たぶん未定義
C#(配列) x[x.Length-1] 例外
C#(配列+Linq) x.Last() 例外
C#(List) x[x.Count-1] 例外
C#(List+Linq) x.Last() 例外
Go x[len(x)-1] パニック
groovy x[-1] 例外
groovy x.last() 例外
JavaScript x[x.length-1] undefined を返す
Objective-C(NSArray) [x lastObject] nil を返す
python x[-1] たぶん例外
R x[length(x)] NULL を返す
ruby x[-1] nil を返す
ruby x.last nil を返す

こうしてみると、C++ って特殊だなと思う。

12
8
2

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
12
8