foreach 루프에서 첫 번째와 마지막 반복을 결정하는 방법은 무엇입니까?
질문은 간단합니다. 나는이 foreach
내 코드에서 루프를 :
foreach($array as $element) {
//code
}
이 루프에서는 처음 또는 마지막 반복에있을 때 다르게 반응하고 싶습니다.
이것을하는 방법?
카운터를 사용할 수 있습니다.
$i = 0;
$len = count($array);
foreach ($array as $item) {
if ($i == 0) {
// first
} else if ($i == $len - 1) {
// last
}
// …
$i++;
}
루프 외부에서 카운터를 초기화하지 않아도되는 솔루션을 선호하는 경우 현재 반복 키를 배열의 마지막 / 첫 번째 키를 알려주는 함수와 비교하는 것이 좋습니다.
이것은 다가오는 PHP 7.3에서 다소 더 효율적이고 읽기 쉽습니다.
PHP 7.3 이상의 솔루션 :
foreach($array as $key => $element) {
if ($key === array_key_first($array))
echo 'FIRST ELEMENT!';
if ($key === array_key_last($array))
echo 'LAST ELEMENT!';
}
모든 PHP 버전에 대한 솔루션 :
foreach($array as $key => $element) {
reset($array);
if ($key === key($array))
echo 'FIRST ELEMENT!';
end($array);
if ($key === key($array))
echo 'LAST ELEMENT!';
}
마지막 항목을 찾기 위해 매번이 코드가 작동한다는 것을 알았습니다.
foreach( $items as $item ) {
if( !next( $items ) ) {
echo 'Last Item';
}
}
위의보다 단순화 된 버전이며 사용자 정의 색인을 사용하지 않는다고 가정합니다 ...
$len = count($array);
foreach ($array as $index => $item) {
if ($index == 0) {
// first
} else if ($index == $len - 1) {
// last
}
}
버전 2-필요하지 않으면 다른 것을 사용하여 싫어하기 때문에.
$len = count($array);
foreach ($array as $index => $item) {
if ($index == 0) {
// first
// do something
continue;
}
if ($index == $len - 1) {
// last
// do something
continue;
}
}
배열에서 첫 번째 요소와 마지막 요소를 제거하고 별도로 처리 할 수 있습니다.
이처럼 :
<?php
$array = something();
$first = array_shift($array);
$last = array_pop($array);
// do something with $first
foreach ($array as $item) {
// do something with $item
}
// do something with $last
?>
인라인 태그 대신 CSS로 모든 서식을 제거하면 코드가 향상되고로드 시간이 단축됩니다.
가능할 때마다 HTML을 PHP 논리와 혼합하는 것을 피할 수도 있습니다.
다음과 같이 분리하면 페이지를 훨씬 더 읽기 쉽고 유지 관리 할 수 있습니다.
<?php
function create_menu($params) {
//retirive menu items
//get collection
$collection = get('xxcollection') ;
foreach($collection as $c) show_collection($c);
}
function show_subcat($val) {
?>
<div class="sub_node" style="display:none">
<img src="../images/dtree/join.gif" align="absmiddle" style="padding-left:2px;" />
<a id="'.$val['xsubcatid'].'" href="javascript:void(0)" onclick="getProduct(this , event)" class="sub_node_links" >
<?php echo $val['xsubcatname']; ?>
</a>
</div>
<?php
}
function show_cat($item) {
?>
<div class="node" >
<img src="../images/dtree/plus.gif" align="absmiddle" class="node_item" id="plus" />
<img src="../images/dtree/folder.gif" align="absmiddle" id="folder">
<?php echo $item['xcatname']; ?>
<?php
$subcat = get_where('xxsubcategory' , array('xcatid'=>$item['xcatid'])) ;
foreach($subcat as $val) show_subcat($val);
?>
</div>
<?php
}
function show_collection($c) {
?>
<div class="parent" style="direction:rtl">
<img src="../images/dtree/minus.gif" align="absmiddle" class="parent_item" id="minus" />
<img src="../images/dtree/base.gif" align="absmiddle" id="base">
<?php echo $c['xcollectionname']; ?>
<?php
//get categories
$cat = get_where('xxcategory' , array('xcollectionid'=>$c['xcollectionid']));
foreach($cat as $item) show_cat($item);
?>
</div>
<?php
}
?>
간단하게 작동합니다!
// Set the array pointer to the last key
end($array);
// Store the last key
$lastkey = key($array);
foreach($array as $key => $element) {
....do array stuff
if ($lastkey === key($array))
echo 'THE LAST ELEMENT! '.$array[$lastkey];
}
최종 문제 를 해결해 주신 @billynoah에게 감사드립니다 .
첫 번째를 찾으려는 시도는 다음과 같습니다.
$first = true;
foreach ( $obj as $value )
{
if ( $first )
{
// do something
$first = false; //in order not to get into the if statement for the next loops
}
else
{
// do something else for all loops except the first
}
}
1 : 왜 간단한 for
진술을 사용하지 않습니까? 실제 배열을 사용한다고 가정 Iterator
하고 카운터 변수가 0인지 또는 전체 요소 수보다 작은 지 쉽게 확인할 수 있습니다. 제 생각에는 이것이 가장 깨끗하고 이해하기 쉬운 솔루션입니다 ...
$array = array( ... );
$count = count( $array );
for ( $i = 0; $i < $count; $i++ )
{
$current = $array[ $i ];
if ( $i == 0 )
{
// process first element
}
if ( $i == $count - 1 )
{
// process last element
}
}
2 : 중첩 구조를 사용하여 트리 구조를 저장하는 것을 고려해야 합니다. 또한 재귀 함수를 사용하여 모든 것을 향상시킬 수 있습니다.
가장 좋은 답변 :
$arr = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
foreach ($arr as $a) {
// This is the line that does the checking
if (!each($arr)) echo "End!\n";
echo $a."\n";
}
@morg 의 가장 효율적인 대답 은와 달리 foreach
해시 맵 객체가 아닌 적절한 배열에서만 작동합니다. 이 대답은 첫 번째 요소와 마지막 요소 를 구체적으로 처리하고 중간 요소를 반복 함으로써 대부분의 이러한 대답 (허용 된 답변 포함)에서와 같이 루프의 모든 반복에 대한 조건 문의 오버 헤드를 피합니다 .
이 array_keys
함수를 사용하면 foreach
다음 과 같은 효율적인 답변을 얻을 수 있습니다 .
$keys = array_keys($arr);
$numItems = count($keys);
$i=0;
$firstItem=$arr[$keys[0]];
# Special handling of the first item goes here
$i++;
while($i<$numItems-1){
$item=$arr[$keys[$i]];
# Handling of regular items
$i++;
}
$lastItem=$arr[$keys[$i]];
# Special handling of the last item goes here
$i++;
나는 이것에 대해 벤치마킹을하지 않았지만 루프에 로직이 추가되지 않았는데, 이는 성능에 가장 큰 타격이되었으므로 효율적인 답변과 함께 제공된 벤치 마크가 매우 가깝다고 생각합니다.
이런 종류의 기능 을 기능화 하고 싶다면 여기 iterateList 함수 에서 스윙을했습니다 . 그러나 효율성에 관심이 있다면 요점 코드를 벤치마킹 할 수 있습니다. 모든 함수 호출에 얼마나 많은 오버 헤드가 도입되는지 잘 모르겠습니다.
SQL 쿼리 생성 스크립트 또는 첫 번째 요소 나 마지막 요소에 대해 다른 작업을 수행하는 작업의 경우 불필요한 변수 검사를 사용하지 않는 것이 훨씬 빠릅니다 (거의 두 배 빠름).
현재 허용되는 솔루션은 루프와 루프 내에서 점검을 사용하여 every_single_iteration이 수행되도록하는 올바른 (빠른) 방법은 다음과 같습니다.
$numItems = count($arr);
$i=0;
$firstitem=$arr[0];
$i++;
while($i<$numItems-1){
$some_item=$arr[$i];
$i++;
}
$last_item=$arr[$i];
$i++;
약간의 수제 벤치 마크는 다음을 보여주었습니다.
test1 : 모델 morg의 100000 실행
시간 : 1869.3430423737 밀리 초
test2 : 마지막 경우 100000 회 실행
시간 : 3235.6359958649 밀리 초
따라서 검사 비용이 많이 든다는 것이 분명합니다. 물론 추가 변수 검사가 많을수록 악화됩니다.)
키와 값을 사용하면 다음과 같이 작동합니다.
foreach ($array as $key => $value) {
if ($value === end($array)) {
echo "LAST ELEMENT!";
}
}
부울 변수를 사용하면이의 첫 등장을 검사 할 경우에도, 여전히 가장 신뢰할 수있다 $value
(I 내 상황에서 많은 상황에서 더 유용하다고) 등과 같이 :
$is_first = true;
foreach( $array as $value ) {
switch ( $value ) {
case 'match':
echo 'appeared';
if ( $is_first ) {
echo 'first appearance';
$is_first = false;
}
break;
}
}
if( !next( $array ) ) {
echo 'last value';
}
}
그런 다음 반복 할 값이 없으면 반환 할 !next( $array )
마지막을 찾는 방법은 무엇 입니까?$value
true
next()
그리고 나는 다음과 같이 카운터를 사용하려고하는 for
대신 루프 를 사용하는 것을 선호합니다 foreach
.
$len = count( $array );
for ( $i = 0; $i < $len; $i++ ) {
$value = $array[$i];
if ($i === 0) {
// first
} elseif ( $i === $len - 1 ) {
// last
}
// …
$i++;
}
같은 문제가있을 때이 스레드를 발견했습니다. 첫 번째 요소 만 가져와야 내 마음에 올 때까지 코드를 다시 분석해야합니다.
$firstElement = true;
foreach ($reportData->result() as $row)
{
if($firstElement) { echo "first element"; $firstElement=false; }
// Other lines of codes here
}
위의 코드는 훌륭하고 완전하지만 첫 번째 요소 만 필요한 경우이 코드를 사용해보십시오.
여전히 필요한지 확실하지 않습니다. 그러나 다음 솔루션은 반복자와 함께 작동해야하며 필요하지 않습니다 count
.
<?php
foreach_first_last(array(), function ($key, $value, $step, $first, $last) {
echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
foreach_first_last(array('aa'), function ($key, $value, $step, $first, $last) {
echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
echo PHP_EOL;
foreach_first_last(array('aa', 'bb', 'cc'), function ($key, $value, $step, $first, $last) {
echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
echo PHP_EOL;
function foreach_first_last($array, $cb)
{
$next = false;
$current = false;
reset($array);
for ($step = 0; true; ++$step) {
$current = $next;
$next = each($array);
$last = ($next === false || $next === null);
if ($step > 0) {
$first = $step == 1;
list ($key, $value) = $current;
if (call_user_func($cb, $key, $value, $step, $first, $last) === false) {
break;
}
}
if ($last) {
break;
}
}
}
익명 기능도 사용할 수 있습니다.
$indexOfLastElement = count($array) - 1;
array_walk($array, function($element, $index) use ($indexOfLastElement) {
// do something
if (0 === $index) {
// first element‘s treatment
}
if ($indexOfLastElement === $index) {
// last not least
}
});
세 가지를 더 언급해야합니다.
- 배열이 엄격하게 (숫자 적으로) 색인화되지 않은 경우
array_values
먼저 배열을 파이프해야합니다 . - 수정이 필요한 경우
$element
참조로 전달해야합니다 (&$element
). - 내부에 필요한 익명 함수 외부의 모든 변수
$indexOfLastElement
는use
구문 내부 옆에 필요에 따라 참조로 다시 나열해야 합니다.
카운터 및 배열 길이를 사용할 수 있습니다.
$ array = 배열 (1,2,3,4); $ i = 0; $ len = count ($ array); foreach ($ arm으로서 $ array) { if ($ i === 0) { // 먼저 } 그렇지 않으면 ($ i === $ len-1) { // 마지막 } //… $ i ++; }
foreach ($arquivos as $key => $item) {
reset($arquivos);
// FIRST AHEAD
if ($key === key($arquivos) || $key !== end(array_keys($arquivos)))
$pdf->cat(null, null, $key);
// LAST
if ($key === end(array_keys($arquivos))) {
$pdf->cat(null, null, $key)
->execute();
}
}
이 시도:
function children( &$parents, $parent, $selected ){
if ($parents[$parent]){
$list = '<ul>';
$counter = count($parents[$parent]);
$class = array('first');
foreach ($parents[$parent] as $child){
if ($child['id'] == $selected) $class[] = 'active';
if (!--$counter) $class[] = 'last';
$list .= '<li class="' . implode(' ', $class) . '"><div><a href="]?id=' . $child['id'] . '" alt="' . $child['name'] . '">' . $child['name'] . '</a></div></li>';
$class = array();
$list .= children($parents, $child['id'], $selected);
}
$list .= '</ul>';
return $list;
}
}
$output .= children( $parents, 0, $p_industry_id);
'development' 카테고리의 다른 글
문자열에서 텍스트를 제거하는 방법? (0) | 2020.02.15 |
---|---|
입력“텍스트”태그 자동 확대 비활성화-iPhone의 Safari (0) | 2020.02.15 |
v = (v == 0? 1 : 0)을 쓰는 더 좋은 방법이 있습니까? (0) | 2020.02.15 |
기능적, 선언적 및 명령형 프로그래밍 (0) | 2020.02.15 |
세션이 실제로 RESTfulness를 위반합니까? (0) | 2020.02.15 |