Print all the elements of the array, three in a wrapper. Tell me how best to implement, as long as I understand the shit. An array of $ images with the number of images (number N) is given. Need to get around it

Пример массива $images[0], $images[1], $images[n] $images[0] => $images[0]['popup'],$images[0]['src'] $images[1] => $images[1]['popup'],$images[1]['src'] $images[n] => $images[n]['popup'],$images[n]['src'] 

 $imax=count($images); for ($i = 0 ; $i < $imax ; $i++) { print '<div class="item">'; $images[$i]['popup']; $i++;if($i==$imax){echo '</div>';break;} $images[$i]['popup']; $i++;if($i==$imax){echo '</div>';break;} $images[$i]['popup']; $i++;if($i==$imax){echo '</div>';break;} print '</div>'; } 

Option decisions taken from the comments -

 $tmpArray = array_chunk($image,3); foreach($tmpArray as $_image) { echo '<div>'; foreach($_image as $_subImage) { echo $_subImage; } echo '</div>'; } 

and

 function split_my($arr, $size) { foreach(array_chunk($arr, $size) as $val) { echo "<div>". implode("", array_map(function($value){ return "<span> ".$value." </span>"; }, $val)). "</div>"; } } 
  • show an example array - ikerya
  • poprobuy poka eto poka pridumayu luchsh for ($ i = 0, $ imax = count ($ images), $ cnt = 0; $ i <$ imax; $ i ++) {$ cnt ++; if ($ cnt == 1) {echo '<div class = "item">'; echo '<span>'. $ images [$ i] ['popup']. '<span>'; } else {if ($ cnt == 3) $ cnt = 0; echo '<span>'. $ images [$ i] ['popup']. '<span>'; }} - Vanya Avchyan
  • array_chunk and implode will save you - splash58
  • @ splash58, do these functions make it easier to output and get fewer lines? - Romuald Shmidtelson
  • of course. first you will immediately beat on the necessary pieces, you will connect the second with divas - splash58

4 answers 4

Well, I usually do this.

If I need to do something with the array, I open the documentation and look at the built-in functions , can they help me. Oops, look, there is an array_chunk , why not.

But this is not all, for passing through all the elements of a subarray, you can use map_array , connect all of this through implode and output. And now let's make it all into a universal function.

 function split_my($arr, $size) { foreach(array_chunk($arr, $size) as $val) { echo "<div>". implode("", array_map(function($value){ return "<span> ".$value." </span>"; }, $val)). "</div>"; } } $arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]; split_my($arr, 3); 

From minuses of the given algorithm - guzzles memory on creation of a copy of array array_chunk . Well, you will have it not $value , but $value['popup'] as far as I understood.

  • It is not very universal - the html code is mixed with php. But so that the memory does not “eat”, you can use array_slice - KoVadim
  • @KoVadim 1. I concentrated on the main task, sort of split the markup or connect the templating engine, this is already a simple matter. Here the main binding for it. 2. I tried to get rid of getting the length of the array and additional calculations explicitly. If you use array_slice, you will have to read the offset and check the returned array for emptiness. And if you use array_splice and get rid of offset, then the problem remains with changing the original array, which may also not be good, and again a test for emptiness. Correct, if somewhere undecided. - Alex Krass
  • the template engine can simply return the result of array_chunk. I would divide into two pieces. But they are afraid of simple calculations, but at the same time saving memory and winning in speed, it is not necessary. But all this needs to be profile, profile and profile again. - KoVadim
  • I will still vote for you, the essence of the answer was to simplify the code, for which those functions that you used serve, I would use implode foreach instead of experiment for the sake of experiment. You told the essence first! Thank you so much - Romuald Shmidtelson

I corrected the decision

  $images = [ ['popup'=>'AAA'], ['popup'=>'BBB'], ['popup'=>'CCC'], ['popup'=>'EEE'], ['popup'=>'FFF'], ['popup'=>'JJJ'], ]; function showItems($images, $step){ $cnt = 0; for ($i = 0 ,$imgCnt=count($images); $i < $imgCnt ; $i++) { $cnt++; if($cnt == 1){ echo '<div class="item">'; } echo '<span>'.$images[$i]['popup'].'</span>'; if($cnt == $step or $i == $imgCnt-1){ $cnt = 0; echo '</div>'; } } } showItems($images, 3); 

The most in my opinion the optimal and short solution. The universal function. Output the number of $ images by the given $ step

  • Your option works, but 1 div is either superfluous or missing. Rather extra - Romuald Shmidtelson
  • so hard .......... - ikerya
  • There is nothing superfluous, everything is correctly opened and closed. I will try to ease it now - Vanya Avchyan
  • And if the number of pictures is not divided by 3 by a whole? - Grundy
  • I had 5 caricas, so something with the number of divs was wrong - Romuald Shmidtelson

Does anyone use iterators?

reset() , current() , next() , prev()

 $i = 0; $html = ''; reset( $images); do { if( 0 === $i%3) $html .= '<div class="item">'; $html .= sprintf('<img src="%s" alt="">', current($images)['popup']); if( 0 === ++$i%3) $html .= '</div>' . PHP_EOL; } while( next( $images)); if( 0 !== $i%3) $html .= '</div>' . PHP_EOL; echo $html; 

Option with array_chunk() and array_map() :

 echo implode("\n", array_map( 'wrapRow', array_chunk( array_map( 'wrapImage', $images), 3 ) ) ); function wrapRow( $els) { return sprintf('<div class="item">%s</div>', implode('', $els)); } function wrapImage($image) { return sprintf('<img src="%s" alt="">', $image['popup']); } 

First, from the $images array, we get an array of <img> tags where the url from the popup field is substituted. Those. same length array, but there are already tags.

Then we beat it into groups of three (or less in the last) using array_chunk() - we get an array of arrays of 3, or less, <img> .

Then we glue these triples implode() and wrap them in <div class="item"> .

And output by gluing <div> 's with a newline character.


  • sorry but downvote but can't go past if in one line, etc. etc. memory on line breaks and {} for the sake of perception is not kosher to save. - Naumov
  • there is no minimizer taste and color) - Sergiks
  • @Naumov, nothing terrible, I compensate)) I liked the option of using another array_map and array_map functions out of limits, unlike my answer with an external foreach . - Alex Krass
  • No, I do not argue, but in the first version you have invented pure foreach php.net/manual/ru/control-structures.foreach.php judging by the documentation. - Naumov
  • @Naumov, I bring the word PHP into the people! :) Here it is pure foreach() , but tomorrow, you may need to walk through a large array back and forth! - Sergiks

I do not understand people who delete answers! Are you afraid of the minuses rating lose?

 for ($i = 0; $i < count($image) ; $i++) { if($i%3 == 0) { echo '<div>'; } echo $image[$i]; if($i%3 == 0) { echo '</div>'; } } if($i%3!=0) { echo '</div>'; // что бы если в конце осталось 2-ва элемента закрыть div } 

or

 $tmpArray = array_chunk($image,3); foreach($tmpArray as $_image) { echo '<div>'; foreach($_image as $_subImage) { echo $_subImage; } echo '</div>'; } 

the second option looks better

  • There is no sense, they are afraid of something. Without errors, nothing will come of it. In the evening I will try all the options. Determining the best becomes harder - Romuald Shmidtelson
  • It was just that there really was a mistake, and there was not much time for correction, so I decided not to litter. - DanielOlivo
  • @DanielOlivo You have only one mistake, at the end you `if ($ i% 3 == 0)` this test of division by 3 was replaced by something else for this, in fact, the div is missing, and of course the last condition. And so the answer was correct. - Naumov
  • one
    for ($ i = 0; $ i <count ($ image); $ i ++) Tak nikogda nedelayut te kto ponimayut v optimizacii, potomuch to pri kajdoy iteracii budet podschitivatsya count ($ image), esli itraciy mnogo to ono sojret mnogo vremeni a pravilno ego peremestit perviy blok vot tak for ($ i = 0, $ cnt = count ($ image); $ i <$ cnt; $ i ++), gde inicializaciya $ cnt = count ($ image) budet odin raz iv ostalnix iteraciyax prosto budet postavlyatsya ego znachenie, chto namnogo luchshe, soglasits - Vanya Avchyan
  • As for me, it is better to take it out for the for loop - Romuald Shmidtelson