(おそらく)連想配列の最初のキーを取得しますか?


756

連想配列の最初のキーを決定する最良の方法は何ですか?私は最初に、配列を単にforeachし、次のようにすぐにそれを壊すと考えました:

foreach ($an_array as $key => $val) break;

したがって、$ keyに最初のキーが含まれていますが、これは非効率的です。誰かがより良い解決策を持っていますか?


4
なぜforeachは非効率的ですか?
エミリオゴート2014年

2
すべての回答と比較すると、foreachは依然として最速のFIDDLE、PHP 5.3です。PHP5.5での私のlocalhostテストは、差がforeachにわずかに有利であることを示しています。
Danijel 2014年

3
@Danijel、foreach意味的に間違っています。
Pacerier、2015

2
@AlexS、どちらかeach($arr)['key']またはeach($arr)[0]機能します。
Pacerier、2015

1
@Danijelこれ以上はありません...キー:0.0107、foreach:0.0217
SeanJA '30

回答:


1337

2019アップデート

始まっPHP 7.3、新しいと呼ばれる機能に建てられているarray_key_first()内部ポインタをリセットせずに指定された配列の最初のキーを取得しますました。詳細については、ドキュメントをご覧ください。


あなたは使用することができますresetkey

reset($array);
$first_key = key($array);

基本的には最初のコードと同じですが、オーバーヘッドが少し少なくなり、何が起こっているかがより明確になります。

を呼び出すことを忘れresetないでください。そうしないと、配列内の任意のキーを取得できます。のend代わりにresetを使用して、最後のキーを取得することもできます。

キーに最初の値を取得させたい場合は、reset実際にそれを返します。

$first_value = reset($array);

ただし、注意が必要な特別なケースが1つあります(最初に配列の長さを確認してください)。

$arr1 = array(false);
$arr2 = array();
var_dump(reset($arr1) === reset($arr2)); // bool(true)

141
補足として、reset()配列の最初の要素(キーではなく値)を返すこともあり、これも便利です。
devios1 2012

5
ドキュメントには、連想配列の最初の値を取得するためにreset() ` reset()と言うコメントがありDon't use ます。これは真の配列に対してはうまく機能しますが、Iteratorオブジェクトに対しては予期せず機能します。bugs.php.net/bug.php?id=38478 `それはまだ本当ですか?私は混乱しています
Dmitry Pashkevich

13
@DmitryPashkevich:そのコメントについて心配しないでください。それらはarrayオブジェクトのことではなく、カスタムオブジェクト(実際の配列ではない)のことです。彼らはデータ構造の違いを混乱させたと思いresetますが、基本的には、最初の「キー」の値を返します。これは、オブジェクト$propの場合、「バグ」レポートの例にありますが、配列の場合、最初のキーです。したがって、心配しないでください。実際の配列(で作成したものarray(…))を使用している限り、問題は発生しません。
Blixt 2013年

2
end()とreset()には副作用があることに注意してください。ただし、世界中のほとんどのコードは、内部ポインタがどこにあるかに依存しないため、これは一般的に問題にはなりません。
ドンキホーテ2014年

1
@ user3019105あなたの関数外の任意のコードが(呼び出すことによって、それを変更した場合に、アレイごとに1つだけの内部ポインタ、手段がありnextresetendまたは配列をループ)を呼び出すとき、あなたが期待値を取得することはありませんがkey。だから、はい、あなたが欲しいものを確実に手に入れるためresetに使用keyする前に必ず電話してください。
Blixt 2014

80

array_keysキーの配列を返します。最初のエントリを取ります。別の方法resetとして、配列を呼び出し、続いてを呼び出すこともできますkey。後者の方法はおそらく少し高速です(テストしなかったと思います)が、内部ポインタをリセットするという副作用があります。


52
これの将来の読者のためのちょうど(遅い)ノート:後者のアプローチは単に「わずかに」速くなるだけではありません。配列全体を反復すること、すべてのキーを別の新しく作成された配列に格納すること、および配列の最初のキーを文字列として要求することには大きな違いがあります。
Blixt 2009

3
質問にopが持っているように、なぜforeachが非効率的で、これらすべての回答と比較されるのですか?
Emilio Gort 14年

5
@EmilioGortいい質問ですね。foreach+ breakreset+のパフォーマンスにkey実際の違いはないと思います。しかし、前者はかなり奇妙に見えるので、スタイルの問題については、後者を好むでしょう。
troelskn

@EmilioGort:Afaik、foreach()は配列を内部的にコピーします。したがって、それはより遅いと仮定できます。(誰かがそれを確認できたら嬉しいでしょう)
donquixote

3
@donquixote確かにわかりませんが、それが通常の配列であり(何らかの種類のオブジェクトやIteratorインターフェースを実装するオブジェクトでforeachはない)とすると、内部コピーが作成されず、ポインターが反復されるだけです。より低レベルの使用と同様nextcurrent
troelsknを

54

興味深いことに、実際にはforeachループが最も効率的な方法です。

OPは効率について具体的に尋ねたため、現在のすべての回答は、実際にはforeachよりもはるかに効率が悪いことを指摘しておく必要があります。

私はこれをphp 5.4でベンチマークしました。リセット/キーポインターメソッド(受け入れられた回答)は、foreachよりも約7倍遅いようです。配列全体(array_keys、array_flip)を操作する他のアプローチはさらに遅いよりも明らかにされているとなる非常に大きな配列を扱う場合に悪化。

Foreachは非効率的ではありません。お気軽にご利用ください!

2015-03-03を編集:

ベンチマークスクリプトがリクエストされました。元のスクリプトはありませんが、代わりにいくつかの新しいテストを行いました。今回は、リセット/キーの約2倍の速さでforeachが見つかりました。私は100キーの配列を使用し、各メソッドを100万回実行して、いくつかの顕著な違いを得ました。ここに簡単なベンチマークのコードを示します。

$array = [];
for($i=0; $i < 100; $i++)
    $array["key$i"] = $i;

for($i=0, $start = microtime(true); $i < 1000000; $i++) {
    foreach ($array as $firstKey => $firstValue) {
        break;
    }
}
echo "foreach to get first key and value: " . (microtime(true) - $start) . " seconds <br />";

for($i=0, $start = microtime(true); $i < 1000000; $i++) {
    $firstValue = reset($array);
    $firstKey = key($array);
}
echo "reset+key to get first key and value: " . (microtime(true) - $start) . " seconds <br />";

for($i=0, $start = microtime(true); $i < 1000000; $i++) {
    reset($array);
    $firstKey = key($array);
}
echo "reset+key to get first key: " . (microtime(true) - $start) . " seconds <br />";


for($i=0, $start = microtime(true); $i < 1000000; $i++) {
    $firstKey = array_keys($array)[0];
}
echo "array_keys to get first key: " . (microtime(true) - $start) . " seconds <br />";

私のphp 5.5ではこれは出力します:

foreach to get first key and value: 0.15501809120178 seconds 
reset+key to get first key and value: 0.29375791549683 seconds 
reset+key to get first key: 0.26421809196472 seconds 
array_keys to get first key: 10.059751987457 seconds

reset + key http://3v4l.org/b4DrN/perf#tabs
foreach http://3v4l.org/gRoGD/perf#tabs


3
どこかにベンチマークがありますか。テストの方法など。とにかく、実行していただきありがとうございます。
インフルエンザ

テスト全体で同じ配列が使用されていることを指摘しておきます。この事実はforeachアプローチに大きな影響を与えると思います。@donquixoteが上記の応答のコメントで述べたように、foreachは配列を内部的にコピーします。配列のコピーを回避すると、このテスト内でのみパフォーマンスが向上するため、ベンチマークの実行中にこのコピーが再利用されると想像できます。
ハルダ2017

2
@Jarda php7 foreach以降、foreachループ内で直接変更しない限り、配列をコピーすることはありません。php5では、配列構造がコピーされる場合があり(refcount> 1の場合)、実際には正しいので、そこに大きな影響を与える可能性があります。幸い、この問題が解決されたphp7では心配する必要はありません。ここでは、foreachが内部でどのように機能するか、および過去にどのように機能したかについて、よく読んでいます。
Webmut 2017

2
上記のベンチマークを使用したphp7.2の時点で、foreachは依然として最速です
ビリーノア

36

key($an_array) 最初のキーを与えます

Blixtごとに編集:ポインターを配列の先頭にリセットするreset($array);key($an_array)に呼び出す必要があります。


7
配列のポインタが最初の要素にない場合があることに注意してください。私の答えを参照してください。
Blixt 2009年

私は最初に配列に要素が1つしかないことを確認しているので、この答えはリセットなしのケースに役立つと思います。おかげで
グルーヴネクター2014


22

2018+の場合

、PHP 7.3以降、array_key_first()これを正確に実現する関数があります。

$array = ['foo' => 'lorem', 'bar' => 'ipsum'];
$firstKey = array_key_first($array); // 'foo'

ドキュメントはこちらから入手できます。😉


21
list($firstKey) = array_keys($yourArray);

2
これはおそらく最も効率的ではありません。
矢田

3
@ヤダ、はい、しかしこれはまれなケースで顕著かもしれません。ほとんどの場合、可読性と保守性ははるかに重要です。また、元のオブジェクト/配列を変更しないソリューションも好みます。例:reset($ ar); $ key = key($ ar); -常に良いアイデアであるとは限らないので、私よりも簡潔なMartyIXのソリューションを選択します。例:array_keys($ ar)[0];
Sergiy Sokolenko

20

効率がそれほど重要でない場合はarray_keys($yourArray)[0]、PHP 5.4以降で使用できます。

例:

# 1
$arr = ["my" => "test", "is" => "best"];    
echo array_keys($arr)[0] . "\r\n"; // prints "my"


# 2
$arr = ["test", "best"];
echo array_keys($arr)[0] . "\r\n"; // prints "0"

# 3
$arr = [1 => "test", 2 => "best"];
echo array_keys($arr)[0] . "\r\n"; // prints "1"

ソリューションに対する利点:

list($firstKey) = array_keys($yourArray);

array_keys($arr)[0]つまり、関数パラメーター(つまりdoSomething(array_keys($arr)[0], $otherParameter))として渡すことができます。

HTH


3
DOESのarray_keys($arr)[0]構文が有効なのですか?
2013年

5
それはPHP 5.4にあります。と呼ばれていarray dereferencingます。例えば参照:schlueters.de/blog/archives/...
マーティンVseticka

@ trante、PHP <5.4を除き、太陽の下ですべての言語で有効です。
Pacerier、2015

13

以下を見つけてください:

$yourArray = array('first_key'=> 'First', 2, 3, 4, 5);
$keys   =   array_keys($yourArray);
echo "Key = ".$keys[0];

実例:


12
$myArray = array(
    2 => '3th element',
    4 => 'first element',
    1 => 'second element',
    3 => '4th element'
);
echo min(array_keys($myArray)); // return 1

1
@jurgemaister max()は、assoc配列の最初のキーを返しません。maxはリストまたは配列項目の最大値を返します
Hamidreza '25 / 07/25

5
OPリクエストではありませんが、状況によっては非常に役立ちます。
d.raev 2014年

9

これも解決策になる可能性があります:

$yourArray = array('first_key'=> 'First', 2, 3, 4, 5);
$first_key = current(array_flip($yourArray));
echo $first_key;

私はそれをテストし、それは動作します。

作業コード


3
array_flip():STRINGおよびINTEGER値のみを反転できます!
Mauro

5

Webmutのソリューションを強化するために、次のソリューションを追加しました。

$firstKey = array_keys(array_slice($array, 0, 1, TRUE))[0];

PHP 7.1での出力は次のとおりです。

foreach to get first key and value: 0.048566102981567 seconds 
reset+key to get first key and value: 0.11727809906006 seconds 
reset+key to get first key: 0.11707186698914 seconds 
array_keys to get first key: 0.53917098045349 seconds 
array_slice to get first key: 0.2494580745697 seconds 

サイズ10000の配列に対してこれを行うと、結果は次のようになります。

foreach to get first key and value: 0.048488140106201 seconds 
reset+key to get first key and value: 0.12659382820129 seconds 
reset+key to get first key: 0.12248802185059 seconds 
array_slice to get first key: 0.25442600250244 seconds 

array_keysメソッドは30秒でタイムアウトします(1000エレメントのみの場合、残りのタイミングはほぼ同じでしたが、array_keysメソッドは約7.5秒でした)。


3
 $arr = array('key1'=>'value1','key2'=>'value2','key3'=>'key3');
 list($first_key) = each($arr);
 print $first_key;
 // key1

3

私のために働いた最良の方法は

array_shift(array_keys($array))

array_keys 初期配列からキーの配列を取得し、それからarray_shift最初の要素値を切り取ります。これにはPHP 5.4以降が必要です。


3

これは私が今まで見つけたより簡単な方法です。高速かつわずか2行のコード:-D

$keys = array_keys($array);
echo $array[$keys[0]];

2

php73:

$array = ['a' => '..', 'b' => '..'];

array_key_first($array); // 'a'
array_key_last($array); // 'b';

http://php.net/manual/en/function.array-key-first.php


1
説明を含めると、投稿の質を高めるのに役立ちます。あなたが将来の読者のための質問に答えていることを覚えておいてください、そしてそれらの人々はあなたのコード提案の理由を知らないかもしれません
MichaelvE

0

ワンライナー:

$array = array('key1'=>'value1','key2'=>'value2','key3'=>'key3');
echo key( array_slice( $array, 0, 1, true ) );

# echos 'key1'

0

今日、POSTリクエストによって返された配列の最初のキーを検索する必要がありました。(そしてフォームIDなどの番号に注意してください)

まあ、私はこれを見つけました: PHPの連想配列の最初のキーを返します

http://php.net/key

私はこれをしました、そしてそれはうまくいきます。

    $data = $request->request->all();
    dump($data);
    while ($test = current($data)) {
        dump($test);
        echo key($data).'<br />';die();
        break;
    }

多分それは他の男の15分を節約するでしょう。CYA。


-2

アレイで遊ぶことができます

$daysArray = array('Monday', 'Tuesday', 'Sunday');
$day = current($transport); // $day = 'Monday';
$day = next($transport);    // $day = 'Tuesday';
$day = current($transport); // $day = 'Tuesday';
$day = prev($transport);    // $day = 'Monday';
$day = end($transport);     // $day = 'Sunday';
$day = current($transport); // $day = 'Sunday';

使用できる配列の最初の要素を取得するにはcurrent、最後の要素には使用できますend

編集する

答えに反対票を投じないようにするためだけに、キーを値に変換できます array_keys上記のようにて使用。


1
これらは値であり、キーではありません。
ビクターシュレーダー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.