[php] 배열의 마지막 요소를 삭제하지 않고 얻는 가장 좋은 방법은 무엇입니까?
확인,
에 대해 모두 알고 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
답변
이 스레드의 많은 답변은 많은 다른 옵션을 제시합니다. 그들로부터 선택할 수 있으려면 그들의 행동과 성과를 이해해야했습니다. 이 대답에 나는 PHP 버전에 대한 벤치마킹, 당신과 함께 내 연구 결과를 공유 할 것 5.6.38
, 7.2.10
그리고 7.3.0RC1
( 2018 12월 13일 예상 ).
<<option code>>
테스트 할 옵션 은 다음과 같습니다.
- 옵션 1.
$x = array_values(array_slice($array, -1))[0];
( 제안 에 의해 rolacja ) - 옵션 .2.
$x = array_slice($array, -1)[0];
( 제안 에 의해 Stoutie ) - 옵션 .3.
$x = array_pop((array_slice($array, -1)));
( 제안 에 의해 rolacja ) - 옵션 .4.
$x = array_pop((array_slice($array, -1, 1)));
( 제안 에 의해 Westy92 ) - 옵션 .5.
$x = end($array); reset($array);
( 제안 에 의해 Iznogood ) - 옵션 .6.
$x = end((array_values($array)));
( 제안 에 의해 TecBrat ) - 옵션 .7.
$x = $array[count($array)-1];
( 제안 에 의해 미르코 Pagliai ) - 옵션 .8.
$keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
( 제안 에 의해 thrau ) - 옵션 .9.
$x = $array[] = array_pop($array);
( 제안 에 의해 user2782001 ) - 옵션 10.
$x = $array[array_key_last($array)];
( 같은 제안 에 의해 콰지모도의 복제 , PHP 7.3 당 가능)
(언급 된 함수 : array_key_last , array_keys , array_pop , array_slice , array_values , count , end , reset )
테스트 입력 <<input code>>
은 다음과 결합됩니다.
- null =
$array = null;
- 비어있는 =
$array = [];
- last_null =
$array = ["a","b","c",null];
- auto_idx =
$array = ["a","b","c","d"];
- 셔플 =
$array = []; $array[1] = "a"; $array[2] = "b"; $array[0] = "c";
- 100 =
$array = []; for($i=0;$i<100;$i++) { $array[] = $i; }
- 100000 =
$array = []; for($i=0;$i<100000;$i++) { $array[] = $i; }
나는를 사용 테스트를 위해 5.6.38
, 7.2.10
그리고 7.3.0RC1
PHP 고정 표시기 컨테이너 와 같은 :
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는 마지막으로 검색된 테스트 입력의 마지막 값을 반환하고 한 반복의 평균 지속 시간을 펨토초 (0.000000000000001 초)로 인쇄합니다.
결과는 다음과 같습니다.
/==========================================================================================================================================================================================================================================================================================================================================================================================================================\
|| || 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의 아탈은 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
이 결과를 바탕으로 다음과 같은 결론을 도출합니다.
- 최신 버전의 PHP는 다음과 같은 옵션을 제외하고 성능이 크게 저하되었습니다.
- 옵션 .6.
$x = end((array_values($array)));
- 옵션 .8.
$keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
- 옵션 .6.
- 이러한 옵션은 매우 큰 배열에 가장 적합합니다.
- 옵션 .5.
$x = end($array); reset($array);
- 옵션 .7.
$x = $array[count($array)-1];
- 옵션 .9.
$x = $array[] = array_pop($array);
- 옵션 10.
$x = $array[array_key_last($array)];
(PHP 7.3부터)
- 옵션 .5.
- 이 옵션은 자동 인덱싱 된 배열에만 사용해야 합니다 .
- 옵션 .7.
$x = $array[count($array)-1];
(사용으로 인해count
) - 옵션 .9.
$x = $array[] = array_pop($array);
(원래 키를 잃는 값을 할당하기 때문에)
- 옵션 .7.
- 이 옵션 은 배열의 내부 포인터를 유지하지 않습니다
- 옵션 .5.
$x = end($array); reset($array);
- 옵션 .5.
- 이 옵션은 옵션 .5 를 수정하려는 시도 입니다. 배열의 내부 포인터를 유지하기 위해 (그러나 슬프게도 매우 큰 배열에서는 잘 확장되지 않습니다)
- 옵션 .6.
$x = end((array_values($array)));
- 옵션 .6.
- 새로운
array_key_last
기능에는이 글을 쓰는 시점에 여전히 RC 인 것을 제외하고는 위에서 언급 한 제한이없는 것 같습니다 (따라서 RC를 사용하거나 2018 년 12 월 릴리스를 기다리십시오).- 옵션 10.
$x = $array[array_key_last($array)];
(PHP 7.3부터)
- 옵션 10.
배열을 스택으로 사용 하는지 또는 대기열로 사용 하는지에 따라 약간의 옵션 9를 변경할 수 있습니다.
답변
시험
$myLastElement = end($yourArray);
재설정하려면 (@hopeseekr 덕분에) :
reset($yourArray);
매뉴얼 링크
@David Murdoch 추가 :
$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와 여러분!
답변
짧고 달다.
오류 메시지를 제거하고 단일 라이너 양식과 효율적인 성능을 유지하는 솔루션을 생각해 냈습니다.
$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
.
답변
무슨 일이야 array_slice($array, -1)
? (매뉴얼 : http://us1.php.net/array_slice 참조 )
array_slice()
배열을 반환합니다. 아마 당신이 찾고있는 것이 아닙니다. 당신은 요소를 원한다.
답변
참조 별 통과 오류를 방지하는 한 가지 방법 (예 : “end (array_values ($ foo))”)은 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))));
답변
내부 포인터를 수정하지 않아도되는 경우 (인덱싱 및 연관 배열 모두 지원) :
// 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($array);
}
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;
레코드 의 경우 배열의 첫 번째 요소에 대한 또 다른 대답이 있습니다.
답변
테스트되지 않은 :이 작동하지 않습니까?
<?php
$last_element=end(array_values($array));
?>
array_values에 의해 반환 된 배열이 멈 췄기 때문에 아무도 포인터가 재설정되는지 신경 쓰지 않습니다.
그리고 당신이 그것을 가지고 갈 열쇠가 필요하다면 나는 당신이 할 것이라고 생각합니다 :
<?php
$last_key=end(array_keys($array));
?>