回答:
あなたはカウンターを使うことができます:
$i = 0;
$len = count($array);
foreach ($array as $item) {
if ($i == 0) {
// first
} else if ($i == $len - 1) {
// last
}
// …
$i++;
}
$i = 1
、心配する必要はありません。$len - 1
使用してください$len
。
ループの外側でカウンターの初期化を必要としないソリューションが必要な場合は、配列の最後/最初のキーを通知する関数と現在の反復キーを比較することをお勧めします。
これは、次の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!';
}
foreach($array as $key => $element) {
reset($array);
if ($key === key($array))
echo 'FIRST ELEMENT!';
end($array);
if ($key === key($array))
echo 'LAST ELEMENT!';
}
end()
+ 最後の要素について話しているだけの場合、それはkey()
ループのすべての反復で+ です。両方の場合、それは毎回呼び出される4つのメソッドです。確かに、これらは非常に軽量な操作であり、おそらく単なるポインタルックアップですが、ドキュメントはそれを指定して配列の内部ポインタreset()
をend()
変更します。カウンタよりも速いのでしょうか。おそらくない。
reset()
呼び出しをforeachの前に移動して、結果をにキャッシュしてください$first
。
最後の項目を見つけるために、私はこのコードが常に機能することを発見しました:
foreach( $items as $item ) {
if( !next( $items ) ) {
echo 'Last Item';
}
}
[true,true,false,true]
ます しかし、個人的には、booleanを含まない配列を扱うときはいつでもこれを使用しますfalse
。
next()
必要がありますNEVER foreachループ内で使用しないこと。内部の配列ポインタを破壊します。詳細については、ドキュメントをご覧ください。
上記のより簡略化されたバージョンで、カスタムインデックスを使用していないと想定しています...
$len = count($array);
foreach ($array as $index => $item) {
if ($index == 0) {
// first
} else if ($index == $len - 1) {
// last
}
}
バージョン2-必要がない限り、elseを使うのが嫌いになったため。
$len = count($array);
foreach ($array as $index => $item) {
if ($index == 0) {
// first
// do something
continue;
}
if ($index == $len - 1) {
// last
// do something
continue;
}
}
if ($index == count($array) - 1)
。こちらをご覧ください。
配列から最初と最後の要素を削除し、個別に処理することができます。
このような:
<?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) {
//retrieve 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
}
?>
最初のものを見つける試みは次のようになります:
$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
}
}
単にこれでうまくいきます!
// 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に感謝します。
if ($key === $lastkey)
ます。
if ($lastkey === $key)
か?
PHP Warning: key() expects parameter 1 to be array, integer given in php shell code on line 1
key()
ではなく、整数を取得していend()
ます。 end()
" は最後の要素の値を返します "、そしてkey()
入力として配列を期待します。
1:単純なfor
ステートメントを使用しないのはなぜですか?実際の配列ではなく実際の配列を使用しているとするとIterator
、counter変数が0であるか、要素の総数よりも1少ないかを簡単に確認できます。私の意見では、これは最もクリーンでわかりやすいソリューションです...
$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:ネストされたセットを使用してツリー構造を保存することを検討する必要があります。さらに、再帰関数を使用して全体を改善できます。
for
からすることができますループ1
にするn-1
と取るif
体からね。それらを繰り返しチェックするポイントはありません。
ベストアンサー:
$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クエリ生成スクリプト、または最初または最後の要素に対して異なるアクションを実行するものの場合、不要な変数チェックの使用を回避する方がはるかに高速(ほぼ2倍高速)です。
現在受け入れられているソリューションでは、ループと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の10万回の実行
時間:1869.3430423737ミリ秒
test2:最後であればモデルの100000回の実行
時間:3235.6359958649ミリ秒
したがって、チェックに多くのコストがかかることは非常に明白です。もちろん、変数チェックを追加するほど、さらに悪化します;)
$arr = array('one' => "1 1 1", 4 => 'Four', 1 => 'One'); $numItems = count($arr); $i=0; $firstitem=$arr[0]; echo $i . ': ' . $firstitem . ", "; $i++; while($i<$numItems-1){ $some_item=$arr[$i]; echo $i . ': ' . $some_item . ", "; $i++; } $last_item=$arr[$i]; echo $i . ': ' . $last_item . ", "; $i++;
出力されます:0: , 1: One, 2: ,
array()
作成された「オブジェクト」は作成されます{'one':"1 1 1",0:"",1:"One",2:"",3:"",4:"Four"}
が、空の要素はcountで無視され、定義された「もの」の数を数えています!! バウンティの犠牲がやって来る!この答えは賞金に値しますが、@ Morgなら。なくなった、それは無意味です。もう二度とSOを使わない人に報奨金をあげよう!彼が戻って答えを改善した場合、彼は賞金に値します!
array_keys
ことができる関数を使用して、ハッシュのプロパティを取得できます。私の「改善された」答えを見てください。
$querySet = ""; foreach ($fieldSet as $key=>$value) { $value = $db->dbLink->quote($value); $querySet .= "$key = $value, "; } $querySet = substr_replace($querySet, "", -2); $queryString = "UPDATE users SET $querySet WHERE user_ID = '$user_ID'";
キーと値を使用すると、これも機能します。
foreach ($array as $key => $value) {
if ($value === end($array)) {
echo "LAST ELEMENT!";
}
}
ブール変数の使用は、次のように、最初の外観を確認したい場合でも、最も信頼性が高くなります$value
(私の状況や多くの状況で、より便利であることがわかりました)。
$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++;
}
それでも必要かどうかはわかりません。ただし、次のソリューションはイテレータで機能し、必要ありません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
}
});
さらに3つの点に言及する必要があります。
array_values
最初に配列をパイプ処理する必要があります。$element
場合は、参照(&$element
)で渡す必要があります。$indexOfLastElement
、use
構造体内の隣にリストする必要があります。これも必要に応じて参照によって行います。カウンタと配列の長さを使用できます。
$ array = array(1,2,3,4); $ i = 0; $ len = count($ array); foreach($ array as $ item){ if($ i === 0){ // 最初 } else if($ 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();
}
}
使用してリセット($配列)と終了($配列)
<?php
$arrays = [1,2,3,4,5];
$first = reset($arrays);
$last = end($arrays);
foreach( $arrays as $array )
{
if ( $first == $array )
{
echo "<li>{$array} first</li>";
}
else if ( $last == $array )
{
echo "<li>{$array} last</li>";
}
else
{
echo "<li>{$array}</li>";
}
}
これを試して:
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);
array_shift
とarray_pop
。これが私がそのようなものを実装しなければならなかった場合に思いついた解決策ですが、今はRok Kraljの答えに固執します。