OK、
私は array_pop()
についてすべて知っていますが、それは最後の要素を削除します。削除せずに配列の最後の要素を取得する最善の方法は何ですか?
編集:これはボーナスです:
$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
あるいは
$array = array('a', 'b', 'c', 'd');
unset($array[2]);
echo $array[sizeof($array) - 1]; // Output: PHP Notice: Undefined offset: 2 in - on line 4
短くて甘い。
私はエラーメッセージを取り除き、ワンライナーフォームと効率的なパフォーマンスを維持するための解決策を思いつきました:
$lastEl = array_values(array_slice($array, -1))[0];
- 以前の解決策
$lastEl = array_pop((array_slice($array, -1)));
注:PHP Strict standards: Only variables should be passed by reference
を回避するには、余分な括弧が必要です。
やってみる
$myLastElement = end($yourArray);
リセットするには(ありがとう@hopeseekr):
reset($yourArray);
@ David Mardoch氏は、次のように付け加えた。$myLastElement = end(array_values($yourArray));// and now you don't need to call reset().
E_STRICTでは、これは警告を生成する
Strict Standards: Only variables should be passed by reference
O_O Tyncとみんなありがとう。
このスレッドの多くの答えは私たちに多くの異なる選択肢を提示します。それらから選択できるようにするために、私は彼らの行動とパフォーマンスを理解する必要がありました。この回答では、PHPバージョン5.6.38
、7.2.10
および7.3.0RC1
( 予想されるDec 13 2018 )を基準にして、私の調査結果をあなたと共有します。
テストするオプション(<<option code>>
s)は次のとおりです。
$x = array_values(array_slice($array, -1))[0];
( 提案どおり by rolacja )$x = array_slice($array, -1)[0];
( 提案どおり by Stoutie )$x = array_pop((array_slice($array, -1)));
( 提案どおり by rolacja )$x = array_pop((array_slice($array, -1, 1)));
( 提案どおり by Westy92 )$x = end($array); reset($array);
( 提案どおり by Iznogood )$x = end((array_values($array)));
( 提案どおり by TecBrat )$x = $array[count($array)-1];
( 提案どおり by Mirko Pagliai )$keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
( 推奨どおり by thrau )$x = $array[] = array_pop($array);
( 推奨どおり by user2782001 )$x = $array[array_key_last($array)];
( 推奨どおり / Quasimodoのクローンによって ; PHP 7.3から利用可能)(言及された機能: array_key_last 、 array_keys 、 array_pop 、 array_slice 、 array_values 、 count 、 end 、 reset )
以下と組み合わせるテスト入力(<<input code>>
s)。
$array = null;
$array = [];
$array = ["a","b","c",null];
$array = ["a","b","c","d"];
$array = []; $array[1] = "a"; $array[2] = "b"; $array[0] = "c";
$array = []; for($i=0;$i<100;$i++) { $array[] = $i; }
$array = []; for($i=0;$i<100000;$i++) { $array[] = $i; }
テストには5.6.38
、7.2.10
そして7.3.0RC1
PHP docker container likeを使います。
Sudo docker run -it --rm php:5.6.38-cli-stretch php -r '<<<CODE HERE>>>'
上記の<<option code>>
sと<<input code>>
sの各組み合わせは、PHPのすべてのバージョンで実行されます。各テスト実行では、次のコードスニペットが使用されます。
<<input code>> error_reporting(E_ALL); <<option code>> error_reporting(0); $before=microtime(TRUE); for($i=0;$i<100;$i++){echo ".";for($j=0;$j<100;$j++){ <<option code>> }}; $after=microtime(TRUE); echo "\n"; var_dump($x); echo round(($after-$before)/(100*100)*1000*1000*1000);
実行ごとに、これはテスト入力の最後に取得した最後の値をvar_dumpし、1反復の平均期間 フェムト秒 (0.000000000000001th of second)を出力します。
結果は以下のとおりです。
/==========================================================================================================================================================================================================================================================================================================================================================================================================================\
|| || T E S T I N P U T - 5 . 6 . 3 8 || T E S T I N P U T - 7 . 2 . 1 0 || T E S T I N P U T - 7 . 3 . 0 R C 1 ||
|| || null | empty | last_null | auto_idx | shuffle | 100 | 100000 || null | empty | last_null | auto_idx | shuffle | 100 | 100000 || null | empty | last_null | auto_idx | shuffle | 100 | 100000 ||
||============================OPTIONS - ERRORS==========================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
|| 1. $x = array_values(array_slice($array, -1))[0]; || W1 + W2 | N1 | - | - | - | - | - || W1 + W2 | N1 | - | - | - | - | - || W1 + W2 | N1 | - | - | - | - | - ||
|| 2. $x = array_slice($array, -1)[0]; || W1 | N1 | - | - | - | - | - || W1 | N1 | - | - | - | - | - || W1 | N1 | - | - | - | - | - ||
|| 3. $x = array_pop((array_slice($array, -1))); || W1 + W3 | - | - | - | - | - | - || W1 + N2 + W3 | N2 | N2 | N2 | N2 | N2 | N2 || W1 + N2 + W3 | N2 | N2 | N2 | N2 | N2 | N2 ||
|| 4. $x = array_pop((array_slice($array, -1, 1))); || W1 + W3 | - | - | - | - | - | - || W1 + N2 + W3 | N2 | N2 | N2 | N2 | N2 | N2 || W1 + N2 + W3 | N2 | N2 | N2 | N2 | N2 | N2 ||
|| 5. $x = end($array); reset($array); || W4 + W5 | - | - | - | - | - | - || W4 + W5 | N2 | N2 | N2 | N2 | N2 | N2 || W4 + W5 | - | - | - | - | - | - ||
|| 6. $x = end((array_values($array))); || W2 + W4 | - | - | - | - | - | - || W2 + N2 + W4 | - | - | - | - | - | - || W2 + N2 + W4 | N2 | N2 | N2 | N2 | N2 | N2 ||
|| 7. $x = $array[count($array)-1]; || - | N3 | - | - | - | - | - || W7 | N3 | - | - | - | - | - || W7 | N3 | - | - | - | - | - ||
|| 8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; || W6 | N3 + N4 | - | - | - | - | - || W6 + W7 | N3 + N4 | - | - | - | - | - || W6 + W7 | N3 + N4 | - | - | - | - | - ||
|| 9. $x = $array[] = array_pop($array); || W3 | - | - | - | - | - | - || W3 | - | - | - | - | - | - || W3 | - | - | - | - | - | - ||
|| 10. $x = $array[array_key_last($array)]; || F1 | F1 | F1 | F1 | F1 | F1 | F1 || F2 | F2 | F2 | F2 | F2 | F2 | F2 || W8 | N4 | F2 | F2 | F2 | F2 | F2 ||
||========================OPTIONS - VALUE RETRIEVED=====================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
|| 1. $x = array_values(array_slice($array, -1))[0]; || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 2. $x = array_slice($array, -1)[0]; || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 3. $x = array_pop((array_slice($array, -1))); || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 4. $x = array_pop((array_slice($array, -1, 1))); || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 5. $x = end($array); reset($array); || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 6. $x = end((array_values($array))); || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | bool(false) | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 7. $x = $array[count($array)-1]; || NULL | NULL | NULL | string(1) "d" | string(1) "b" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "b" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "b" | int(99) | int(99999) ||
|| 8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 9. $x = $array[] = array_pop($array); || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) || NULL | NULL | NULL | string(1) "d" | string(1) "c" | int(99) | int(99999) ||
|| 10. $x = $array[array_key_last($array)]; || N/A | N/A | N/A | N/A | N/A | N/A | N/A || N/A | N/A | N/A | N/A | N/A | N/A | N/A || N/A | N/A | N/A | N/A | N/A | N/A | N/A ||
||=================OPTIONS - FEMTOSECONDS PER ITERATION=================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
|| 1. $x = array_values(array_slice($array, -1))[0]; || 803 | 466 | 390 | 384 | 373 | 764 | 1.046.642 || 691 | 252 | 101 | 128 | 93 | 170 | 89.028 || 695 | 235 | 90 | 97 | 95 | 188 | 87.991 ||
|| 2. $x = array_slice($array, -1)[0]; || 414 | 349 | 252 | 248 | 246 | 604 | 1.038.074 || 373 | 249 | 85 | 91 | 90 | 164 | 90.750 || 367 | 224 | 78 | 85 | 80 | 155 | 86.141 ||
|| 3. $x = array_pop((array_slice($array, -1))); || 724 | 228 | 323 | 318 | 350 | 673 | 1.042.263 || 988 | 285 | 309 | 317 | 331 | 401 | 88.363 || 877 | 266 | 298 | 300 | 326 | 403 | 87.279 ||
|| 4. $x = array_pop((array_slice($array, -1, 1))); || 734 | 266 | 358 | 356 | 349 | 699 | 1.050.101 || 887 | 288 | 316 | 322 | 314 | 408 | 88.402 || 935 | 268 | 335 | 315 | 313 | 403 | 86.445 ||
|| 5. $x = end($array); reset($array); || 715 | 186 | 185 | 180 | 176 | 185 | 172 || 674 | 73 | 69 | 70 | 66 | 65 | 70 || 693 | 65 | 85 | 74 | 68 | 70 | 69 ||
|| 6. $x = end((array_values($array))); || 877 | 205 | 320 | 337 | 304 | 2.901 | 7.921.860 || 948 | 300 | 336 | 308 | 309 | 509 | 29.696.951 || 946 | 262 | 301 | 309 | 302 | 499 | 29.234.928 ||
|| 7. $x = $array[count($array)-1]; || 123 | 300 | 137 | 139 | 143 | 140 | 144 || 312 | 218 | 48 | 53 | 45 | 47 | 51 || 296 | 217 | 46 | 44 | 53 | 53 | 55 ||
|| 8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; || 494 | 593 | 418 | 435 | 399 | 3.873 | 12.199.450 || 665 | 407 | 103 | 109 | 114 | 431 | 30.053.730 || 647 | 445 | 91 | 95 | 96 | 419 | 30.718.586 ||
|| 9. $x = $array[] = array_pop($array); || 186 | 178 | 175 | 188 | 180 | 181 | 186 || 83 | 78 | 75 | 71 | 74 | 69 | 83 || 71 | 64 | 70 | 64 | 68 | 69 | 81 ||
|| 10. $x = $array[array_key_last($array)]; || N/A | N/A | N/A | N/A | N/A | N/A | N/A || N/A | N/A | N/A | N/A | N/A | N/A | N/A || 370 | 223 | 49 | 52 | 61 | 57 | 52 ||
\=========================================================================================================================================================================================================================================================================================================================================================================================================================/
上記の _ f _ atal、 _ w _ arning、および _ n _ oticeコードは、次のように変換されます。
F1 = Fatal error: Call to undefined function array_key_last() in Command line code on line 1
F2 = Fatal error: Uncaught Error: Call to undefined function array_key_last() in Command line code:1
W1 = Warning: array_slice() expects parameter 1 to be array, null given in Command line code on line 1
W2 = Warning: array_values() expects parameter 1 to be array, null given in Command line code on line 1
W3 = Warning: array_pop() expects parameter 1 to be array, null given in Command line code on line 1
W4 = Warning: end() expects parameter 1 to be array, null given in Command line code on line 1
W5 = Warning: reset() expects parameter 1 to be array, null given in Command line code on line 1
W6 = Warning: array_keys() expects parameter 1 to be array, null given in Command line code on line 1
W7 = Warning: count(): Parameter must be an array or an object that implements Countable in Command line code on line 1
W8 = Warning: array_key_last() expects parameter 1 to be array, null given in Command line code on line 1
N1 = Notice: Undefined offset: 0 in Command line code on line 1
N2 = Notice: Only variables should be passed by reference in Command line code on line 1
N3 = Notice: Undefined offset: -1 in Command line code on line 1
N4 = Notice: Undefined index: in Command line code on line 1
この出力に基づいて、私は以下の結論を導きます。
$x = end((array_values($array)));
$keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
$x = end($array); reset($array);
$x = $array[count($array)-1];
$x = $array[] = array_pop($array);
$x = $array[array_key_last($array)];
(PHP 7.3以降)$x = $array[count($array)-1];
(count
の使用による)$x = $array[] = array_pop($array);
(値を代入すると元のキーが失われるため)$x = end($array); reset($array);
$x = end((array_values($array)));
array_key_last
関数には上記の制限はありません(RCを使用するか、2018年12月のリリースを待ってください)。$x = $array[array_key_last($array)];
(PHP 7.3以降)配列をスタックとして使用するのか、キューとして使用するのかに応じて、 オプション9を変更することができます。
array_slice($array, -1)
の何が問題になっていますか? (マニュアル参照: http://us1.php.net/array_slice )
array_slice()
は配列を返します。おそらくあなたが探しているものではありません。あなたはその要素が欲しいのです。
参照渡しエラー(例: "end(array_values($ foo))")を回避する1つの方法は、call_user_funcまたはcall_user_func_arrayを使用することです。
// PHP Fatal error: Only variables can be passed by reference
// No output (500 server error)
var_dump(end(array(1, 2, 3)));
// No errors, but modifies the array's internal pointer
// Outputs "int(3)"
var_dump(call_user_func('end', array(1, 2, 3)));
// PHP Strict standards: Only variables should be passed by reference
// Outputs "int(3)"
var_dump(end(array_values(array(1, 2, 3))));
// No errors, doesn't change the array
// Outputs "int(3)"
var_dump(call_user_func('end', array_values(array(1, 2, 3))));
テストされていない:これはうまくいきませんか?
<?php
$last_element=end(array_values($array));
?>
Array_valuesによって返された配列は一瞬であるため、ポインタがリセットされても気にする必要はありません。
あなたがそれと一緒に行くための鍵が必要な場合、私はあなたがすると思います:
<?php
$last_key=end(array_keys($array));
?>
内部ポインタを変更することを気にしないのであれば(添字配列と連想配列の両方をサポートする):
// false if empty array
$last = end($array);
// null if empty array
$last = !empty($array) ? end($array) : null;
内部ポインタを変更しないユーティリティ関数が必要な場合(配列が値渡しされ、その関数がそのコピーを処理するため):
function array_last($array) {
if (empty($array)) {
return null;
}
return end($value);
}
PHPは「オンザフライ」で、つまり実際に必要なときにのみコピーを作成します。 end()
自体が配列を変更するので、内部的に配列のコピーが生成されます。
したがって、次の方法は内部的には配列をコピーせず、スライスを作成するだけなので実際には高速です。
function array_last($array) {
if (empty($array)) {
return null;
}
foreach (array_slice($array, -1) as $value) {
return $value;
}
}
この「foreach/return」は最初の(そしてここでは単一の)アイテムを効率的に取得するための微調整です。
最後に、最も高速な方法ですが、インデックス付き配列のみを対象としています。
$last = !empty($array) ? $array[count($array)-1] : null;
記録のために、これは もう一つの答え の、配列の最初の要素です。
私はスタックを扱うためにこれをかなり頻繁に必要とします、そして私はいつも自分自身が配列やその内部ポインタを何らかの形で操作することなしにそれをするネイティブ関数がないことに困惑しています。
だから私は通常連想配列でも安全に使えるutil関数を持ち歩いています。
function array_last($array) {
if (count($array) < 1)
return null;
$keys = array_keys($array);
return $array[$keys[sizeof($keys) - 1]];
}
end()は配列の最後の要素を提供します
$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
echo end($array); //output: c
$array1 = array('a', 'b', 'c', 'd');
echo end($array1); //output: d
配列の最後の要素を取得するには、次のようにします。
$lastElement = array_slice($array, -1)[0];
基準
私は1000回繰り返し、それぞれ100個と50,000個の要素を含む小さい配列と大きい配列の最後の要素をつかみました。
Method: $array[count($array)-1];
Small array (s): 0.000319957733154
Large array (s): 0.000526905059814
Note: Fastest! count() must access an internal length property.
Note: This method only works if the array is naturally-keyed (0, 1, 2, ...).
Method: array_slice($array, -1)[0];
Small array (s): 0.00145292282104
Large array (s): 0.499367952347
Method: array_pop((array_slice($array, -1, 1)));
Small array (s): 0.00162816047668
Large array (s): 0.513121843338
Method: end($array);
Small array (s): 0.0028350353241
Large array (s): 4.81077480316
Note: Slowest...
私はPHPバージョン5.5.32を使いました。
PHPバージョン7.3以降、関数array_key_first
およびarray_key_last
が導入されました。
PHPの配列は厳密な配列型、つまりインデックス0から始まる固定サイズフィールドの固定サイズのコレクションではないので、動的拡張連想配列であるため、未知のキーを持つ位置の処理は難しく、回避策は非常に困難です。そうですね。これとは対照的に、実数配列はポインタ算術を介して非常に高速に内部的にアドレス指定され、最後のインデックスは宣言時にコンパイル時にすでに認識されています。
少なくとも最初と最後の位置に関する問題は、バージョン7.3以降の組み込み関数によって解決されています。これは 配列リテラル に何の警告もなしに動作します。
$first = array_key_first( [1, 2, 'A'=>65, 'B'=>66, 3, 4 ] );
$last = array_key_last ( [1, 2, 'A'=>65, 'B'=>66, 3, 4 ] );
明らかに最後の value は:
$array[array_key_last($array)];
$lastValue = end(array_values($array))
$ arrayポインタに変更は加えられていません。これは避けます
reset($array)
ある条件ではこれは望ましくないかもしれません。
私のために:
$last = $array[count($array) - 1];
連想と:
$last =array_values($array)[count($array - 1)]
どうですか?
current(array_slice($array, -1))
$array == []
(false
を返す)の場合に機能します。別の解決策:
$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
$lastItem = $array[(array_keys($array)[(count($array)-1)])];
echo $lastItem;
End()関数を使用してください。
$array = [1,2,3,4,5];
$last = end($array); // 5
注:(PHP 7> = 7.3.0) を使用できますarray_key_last - 配列の最後のキーを取得
array_key_last ( array $array ) : mixed
これを行い、E_STRICTを避け、配列の内部ポインタを混乱させないようにするには、次のようにします。
function lelement($array) {return end($array);}
$last_element = lelement($array);
lelementはコピーに対してのみ機能するので、配列のポインタには影響しません。
もう一つの可能な解決策...
$last_element = array_reverse( $array )[0];
今日では、 php.net/end answer で示唆されているように、私は常にこのヘルパーを持っていることを好みます。
<?php
function endc($array) {
return end($array);
}
$items = array('one','two','three');
$lastItem = endc($items); // three
$current = current($items); // one
?>
これは常にポインタをそのままにしておくので、括弧や厳格な基準などについて心配する必要はありません。
Arrayから最後の値を取得する場合:
array_slice($arr,-1,1) ;
配列から最後の値を削除する場合:
array_slice($arr,0,count($arr)-1) ;
これは、既存のすべての答えを少し改善したものだと思います。
$lastElement = count($array) > 0 ? array_values(array_slice($array, -1))[0] : null;
end()
やarray_keys()
を使用したソリューションよりも優れたパフォーマンスを発揮します。単に:$last_element = end((array_values($array)))
配列をリセットせず、STRICT警告を出しません。
PS。最も投票された回答にまだ二重括弧がないので、私はこの回答を提出しました。
上の答えは素晴らしいですが、@ paul-van-leeuwenと@ quasimodos-cloneで述べたように、PHP 7.3はこの問題を直接解決するための2つの新しい関数を導入します - array_key_first() そして array_key_last() 。
以下のpolyfill(またはshim)関数を使って、今日この構文を使い始めることができます。
// Polyfill for array_key_last() available from PHP 7.3
if (!function_exists('array_key_last')) {
function array_key_last($array) {
return array_slice(array_keys($array),-1)[0];
}
}
// Polyfill for array_key_first() available from PHP 7.3
if (!function_exists('array_key_first')) {
function array_key_first($array) {
return array_slice(array_keys($array),0)[0];
}
}
// Usage examples:
$first_element_key = array_key_first($array);
$first_element_value = $array[array_key_first($array)];
$last_element_key = array_key_last($array);
$last_element_value = $array[array_key_last($array)];
警告:これにはPHP 5.4以上が必要です。
以下のロジックを使用して、配列から最後の要素を簡単に取得できます
$array = array('a', 'b', 'c', 'd');
echo ($array[count($array)-1]);
最後の要素だけでなく、以下のロジックを使用して、最後から2番目、最後から3番目などを取得することもできます。
最後から2番目の要素については、たとえば上記のステートメントで2番のみを渡す必要があります。
echo($ array [count($ array)-2]);
PHP 7.3以降、これは利用可能です
$ lastEl = $ myArray [array_key_last($ myArray [))
$file_name_dm = $_FILES["video"]["name"];
$ext_thumb = extension($file_name_dm);
echo extension($file_name_dm);
function extension($str){
$str=implode("",explode("\\",$str));
$str=explode(".",$str);
$str=strtolower(end($str));
return $str;
}