[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>>테스트 할 옵션 은 다음과 같습니다.

(언급 된 함수 : 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]];
  • 이러한 옵션은 매우 큰 배열에 가장 적합합니다.
    • 옵션 .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부터)
  • 이 옵션은 자동 인덱싱 된 배열에만 사용해야 합니다 .
    • 옵션 .7. $x = $array[count($array)-1];(사용으로 인해count)
    • 옵션 .9. $x = $array[] = array_pop($array);(원래 키를 잃는 값을 할당하기 때문에)
  • 이 옵션 은 배열의 내부 포인터를 유지하지 않습니다
    • 옵션 .5. $x = end($array); reset($array);
  • 이 옵션은 옵션 .5 를 수정하려는 시도 입니다. 배열의 내부 포인터를 유지하기 위해 (그러나 슬프게도 매우 큰 배열에서는 잘 확장되지 않습니다)
    • 옵션 .6. $x = end((array_values($array)));
  • 새로운 array_key_last기능에는이 글을 쓰는 시점에 여전히 RC 인 것을 제외하고는 위에서 언급 한 제한이없는 것 같습니다 (따라서 RC를 사용하거나 2018 년 12 월 릴리스를 기다리십시오).
    • 옵션 10. $x = $array[array_key_last($array)]; (PHP 7.3부터)

배열을 스택으로 사용 하는지 또는 대기열로 사용 하는지에 따라 약간의 옵션 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));
?>