質問は簡単です。私のコードには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では、これはやや効率的になり(そして読みやすくなります)。
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!';
}
最後の項目を見つけるために、このコードが毎回機能することを確認します。
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 - 私が必要な場合を除いてelseを使ってatheくようになったから。
$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
}
?>
最初のものを見つける試みは次のようになります。
$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];
}
end の問題を整理してくれてありがとう@billynoah。
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:ツリー構造を保存するために Nested Sets の使用を検討してください。さらに、再帰関数を使って全体を改善することができます。
ベストアンサー:
$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";
}
foreach
とは異なり、ほとんどの 効率的な答え @morgからは、ハッシュマップオブジェクトではなく、適切な配列に対してのみ機能します。この回答は、ループのすべての反復での条件文のオーバーヘッドを回避します。これらの回答のほとんど(受け入れられた回答を含む)のように、具体的に最初と最後の要素を処理し、中央の要素をループします。
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++;
私はこれについてベンチマークを行っていませんが、ループにロジックが追加されていないため、パフォーマンスへの最大の影響が発生するため、効率的な回答で提供されるベンチマークはかなり近いと思われます。
このようなことをfunctionalizeしたい場合は、このような iterateList関数 でスイングしました。ただし、効率が非常に重要な場合は、Gistコードのベンチマークを行うことをお勧めします。すべての関数呼び出しがどれだけのオーバーヘッドをもたらすかはわかりません。
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の100000回の実行
時間:1869.3430423737ミリ秒
test2:最後の場合はモデルの100000回の実行
時間:3235.6359958649ミリ秒
そして、チェックに多大なコストがかかることは明らかです。もちろん、より多くの変数チェックを追加すると、さらに悪化します。
キーと値の場合、これは同様に機能します。
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
を見つけ、繰り返すnext()
値がなければtrue
を返すようにしましょう。
このようにカウンタを使うのであれば、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;
}
}
}
あなたは、カウンタと配列の長さを使うことができます。
$ array = array(1,2,3,4); $ i = 0; $ len = count($ array); foreach($ itemとしての$配列){ if($ i === 0){ //最初の }そうでなければ($ i === $ len - 1){ // last } //… $ i ++; }
無名関数を使うこともできます。
$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
)。use
構文の内側の$indexOfLastElement
の横にリストする必要があります。