Having 3 multidimensional arrays, to whom I do a foreach how can I limit the multidimensional response inside foreach from X items to lets say 20.
Code:
$i = 0;
foreach ($value->channel->item as $item)
{
$data['data'][$keySection]['item1'][$i]['url'] = $item->url;
$data['data'][$keySection]['item1'][$i]['title'] = $item->title;
$data['data'][$keySection]['item1'][$i]['img'] = $item->thumb;
$i++;
}
where $value is contained within
foreach ($homeData as $keySection => $valueSection)
{
foreach($valueSection as $key => $value)
{
switch ($key)
{
I've tried aplying some fors both within foreach ($value->channel->item as $item) as outside but I just can't get it to work properly, I get either doubled results or not working at all.
How can I make this work??
Edit:
$i has nothing to do with it... I need to limit $value->channel->item where item contains X results
Edit2:
$i is for $homeData where $homeData contains three values and each and one of those will later contain 3 different values of $value->channel->item so if item contains 20 results, will be 3x20 = 60 and $i is ment to separate each 20 results...
Edit3:
ok, now I get it... sorry for the misunderstanding
After you start the foreach, add:
if($i > 19) {
break;
}
This checks if $i is greater than 19 (which means 20 iterations) and then breaks this foreach loop. More information about break, here.
You can do it like :
$i = 0;
foreach ($value->channel->item as $item)
{
if($i > 19) {
break;
}
$data['data'][$keySection]['item1'][$i]['url'] = $item->url;
$data['data'][$keySection]['item1'][$i]['title'] = $item->title;
$data['data'][$keySection]['item1'][$i]['img'] = $item->thumb;
$i++;
}
This will give you 20 items.
Hope this is what you want :)
Related
Sorry for the title as it looks like most of the other questions about combining arrays, but I don't know how to write it more specific.
I need a PHP function, which combines the entries of one array (dynamic size from 1 to any) to strings in every possible combination.
Here is an example with 4 entries:
$input = array('e1','e2','e3','e4);
This should be the result:
$result = array(
0 => 'e1',
1 => 'e1-e2',
2 => 'e1-e2-e3',
3 => 'e1-e2-e3-e4',
4 => 'e1-e2-e4',
5 => 'e1-e3',
6 => 'e1-e3-e4',
7 => 'e1-e4'
8 => 'e2',
9 => 'e2-e3',
10 => 'e2-e3-e4',
11 => 'e2-e4',
12 => 'e3',
13 => 'e3-e4',
14 => 'e4'
);
The sorting of the input array is relevant as it affects the output.
And as you see, there should be an result like e1-e2 but no e2-e1.
It seems really complicated, as the input array could have any count of entries.
I don't even know if there is a mathematical construct or a name which describes such a case.
Has anybody done this before?
You are saying that there might be any number of entries in the array so I'm assuming that you aren't manually inserting the data and there would be some source or code entering the data. Can you describe that? It might be easier to directly store it as per your requirement than having an array and then changing it as per your requirement
This might be helpful Finding the subsets of an array in PHP
I have managed to bodge together a code that creates the output you want from the input you have.
I think I have understood the logic of when and why each item looks the way it deos. But Im not sure, so test it carefully before using it live.
I have a hard time explaining the code since it's really a bodge.
But I use array_slice to grab the values needed in the strings, and implode to add the - between the values.
$in = array('e1','e2','e3','e4');
//$new =[];
$count = count($in);
Foreach($in as $key => $val){
$new[] = $val; // add first value
// loop through in to greate the long incrementing string
For($i=$key; $i<=$count-$key;$i++){
if($key != 0){
$new[] = implode("-",array_slice($in,$key,$i));
}else{
if($i - $key>1) $new[] = implode("-",array_slice($in,$key,$i));
}
}
// all but second to last except if iteration has come to far
if($count-2-$key >1) $new[] = Implode("-",Array_slice($in,$key,$count-2)). "-". $in[$count-1];
// $key (skip one) next one. except if iteration has come to far
If($count-2-$key >1) $new[] = $in[$key] . "-" . $in[$key+2];
// $key (skip one) rest of array except if iteration has come to far
if($count-2-$key > 1) $new[] = $in[$key] ."-". Implode("-",Array_slice($in,$key+2));
// $key and last item, except if iteration has come to far
if($count-1 - $key >1) $new[] = $in[$key] ."-". $in[$count-1];
}
$new = array_unique($new); // remove any duplicates that may have been created
https://3v4l.org/uEfh6
here is a modificated version of Finding the subsets of an array in PHP
function powerSet($in,$minLength = 1) {
$count = count($in);
$keys = array_keys($in);
$members = pow(2,$count);
$combinations = array();
for ($i = 0; $i < $members; $i++) {
$b = sprintf("%0".$count."b",$i);
$out = array();
for ($j = 0; $j < $count; $j++) {
if ($b{$j} == '1') {
$out[] = $keys[$j];
}
}
if (count($out) >= $minLength) {
$combinations[] = $out;
}
}
$result = array();
foreach ($combinations as $combination) {
$values = array();
foreach ($combination as $key) {
$values[$key] = $in[$key];
}
$result[] = implode('-', $values);
}
sort($result);
return $result;
}
This seems to work.
How may i know that - In php how many times the foreach loop will get run, before that loop get executed..In other words i want to know the count of that particular loop. I want to apply some different css depends upon the count.
Use the function count to get the amount of numbers in your array.
Example:
$array = array('test1', 'test2');
echo count($array); // Echos '2'
Or if you want to be an engineer for-sorts you can set up something like so:
$array = array('test1', 'test2');
$count = 0;
foreach ($array as $a) { $count++; }
And that can count it for you, and the $count variable will hold the count, hope this helped you.
Simply count() the array and use the output as a condition, like:
if (count($array) > 100) {
// This is an array with more than 100 items, go for plan A
$class = 'large';
} else {
// This is an array with less than 100 items, go for plan B
$class = 'small';
}
foreach ($array as $key => $value) {
echo sprintf('<div id="%s" class="%s">%s</div>', $key, $class, $value);
}
Well I'm stuck with this one.
I have a foreach loop nested in another foreach loop. Now on certain conditions I need to run the outer loop once again with the same key.
While there is this function prev($array), which would set the iterator to the previous position, this does not seem to work and the php docs says
As foreach relies on the >internal array pointer, changing it within the loop may lead to unexpected behavior.
The array I am working on is an associative array, so obviously I cannot easily switch to integer indexed iterations.
$arrLocalCopy = $this->arrPrintOut;
$groupCounter = 0;
foreach($this->arrPrintOut as $kOne => $rowA){
//first and last row contain titles and totals, so we skip them
if($groupCounter < 1 || $groupCounter == sizeof($this->arrPrintOut)-1 ){ $groupCounter++; continue; }
$rowCounter = 0;
foreach($arrLocalCopy as $k => $rowB){
//skip rows that are "before" the outer loops row, as we want to compare only rows below the row we compare to.
if ($rowCounter <= $groupCounter || $rowCounter == sizeof($arrLocalCopy)-1 ) { $rowCounter++; continue; }
//If those values are the same, then values belong to the same group and must be summed together.
if($rowA['t']==$rowB['t'] && $rowA['y']==$rowB['y'] && $rowA['g']==$rowB['g'] && $rowA['q']==$rowB['q'])
{
//if values are the same, then data belongs to one group, lets group them together.
$this->arrPrintOut[$kOne]['s'] += $rowB['s'];
$this->arrPrintOut[$kOne]['b'] += $rowB['b'];
$this->arrPrintOut[$kOne]['v'] += $rowB['v'];
$this->arrPrintOut[$kOne]['r'] += $rowB['r'];
$this->arrPrintOut[$kOne]['k'] += $rowB['k'];
$this->arrPrintOut[$kOne]['n'] += $rowB['n'];
$this->arrPrintOut[$kOne]['m'] += $rowB['m'];
$this->arrPrintOut[$kOne]['l'] += $rowB['l'];
unset($this->arrPrintOut[$k]); //row has been grouped to the current row, so we remove it from the array and from the copy.
unset($arrLocalCopy[$k]);
prev($this->arrPrintOut); //we need to run the outer loop with the same key again, as probably there is another row which could be grouped together with this row.
$groupCounter--;
}
$rowCounter++;
}
$groupCounter++;
}
Here is a code sample.
$rollback is a variable to check if we prev() already
$max is the number of iterations. If you prev() you have to increment it.
<?php
$array = array(1 => "a", 6 => "b", 19 => "c");
$rollback=0;
$max = sizeof($array);
for ($i=0; $i<$max; $i++) {
$key = key($array);
$value = $array[$key];
print "$key => $value\n";
next($array);
if ($value == "b" && $rollback == 0) {
prev($array);
$rollback = 1;
$max++;
}
}
I have code that will make an array or arrays of UNKNOWN length because it depends on how many new people have been added to the mysql DB. (this is where I'm getting confused)
The array has $x items, each item is an array of first name, last name, and e-mail address.
I want the loop to run till the array is ended.
$x = 0;
while($array[$x]['per_LastName'] != 'NULL') {
$batch[] = array('EMAIL'=>$array[$x]['per_Email'], 'FNAME'=>$array[$x]['per_FirstName'], 'LNAME'=>$array[$x]['per_LastName']);
$x = $x+1;
}
apparently I'm looping infinity because it uses all the memory.
Use a foreach loop which will loop through all elements of the array.
foreach($array as $key => $value) {
$batch[] = array('EMAIL'=>$value['per_Email'], 'FNAME'=>$value['per_FirstName'], 'LNAME'=>$value['per_LastName']);
}
Instead you should use a for loop
for($x = 0; $x<count($array); $x++){
$batch[] = array('EMAIL'=>$array[$x]['per_Email'], 'FNAME'=>$array[$x]['per_FirstName'], 'LNAME'=>$array[$x]['per_LastName']);
}
why not use foreach and avoid counters and unnecessary checks?
foreach($array as $eachArray)
{
$batch[] = array('EMAIL'=>$eachArray['per_Email'], 'FNAME'=>$eachArray['per_FirstName'], 'LNAME'=>$eachArray['per_LastName']);
}
am working on php loops and i find myself that i need to write a nested loop bur when i try to combine foreach and for loop it yield to unexpected result
Here are my codes
foreach ($district_ward as $key => $value) {
$ward_ids = array_keys($district_ward[$key]);
echo $key;
for ($x = 0; $x < count($ward_ids)-1; $x++) {
$district_village[$key]= array_merge($value[$ward_ids[$x]], $value[$ward_ids[$x+1]]);
}
}
This gives me this
347
but when i print the value of $key within the for loop, that is
foreach ($district_ward as $key => $value) {
$ward_ids = array_keys($district_ward[$key]);
for ($x = 0; $x < count($ward_ids)-1; $x++) {
echo $key;
$district_village[$key]= array_merge($value[$ward_ids[$x]], $value[$ward_ids[$x+1]]);
}
}
i get this
3
I'm just going to guess that your 2nd and 3rd array are only one entry long. The condition for the loop specifies $x < count($ward_ids) - 1. If your array only has one entry, one - 1 will make it loop 0 times. In other words, your inner loop is not executed at all.
Are you printing this to a html page? Are your keys 3, 4 and 7? They would appear as 347 if you were echoing to an html page. Try
echo "$key<br />\n";
or even
echo "<pre>".print_r($district_ward)."</pre>";
before the loop to see what the array looks like.
foreach ($district_ward as $key => $value) {
$ward_ids = array_keys($district_ward[$key]);
for ($x = 0; $x < count($ward_ids); $x++) {
echo $key;
$district_village[$key]= array_merge($value[$ward_ids[$x]], $value[$ward_ids[$x+1]]);
}
}
Should do the trick, this because you start at 0 up UNTIL the amount of $ward_ids
Let's say your $ward_ids has 1 entry, then you would have looped 0 till 0, so no loops at all,
And lets say it had 102 entries, then you would have looped 1-101, leaving 102 out since you started at 0.