PHP make array go back to 0 when reached last item - php

I have an array with 6 different colors in it like this:
$colors = array(
'dd0330',
'e49fca',
'a776a6',
'f7e300',
'f78f1e',
'd12a2f',
);
And I have a loop where I store some stuff in an array, I add for every element a color. But the array can have more items than 6 so when the sixth color is being gifted out I want the counter to be reset
This is what I've tried:
$loop_counter = 0;
if ( $orders->have_posts() ){
while ($orders->have_posts()) : $orders->the_post();
...
$myOrders[] = array( 'name' => $name,
'schedule' => $activiteiten,
'link' => $link,
'color' => $colors[$loop_counter],
'catering' => $catering,
);
...
if($loop_counter = 5){
$loop_counter = 0;
}
$loop_counter++;
endwhile;
}
But this seems to give my first item the first color and everythin else the second one.
Anyone know how I can reset my counter?
Many thanks in advance!

So close!
Try
if($loop_counter == 5)
You need an equivalence relation, not an equals
Also, if you're going to have your $loop_counter++ after the if, your if should set $loop_counter = -1.

You can do better.
$myOrders[] = array( 'name' => $name,
'schedule' => $activiteiten,
'link' => $link,
'color' => $colors[$loop_counter % 6],
'catering' => $catering,
);
% gives you a remainder, and you never have to check and reset the counter.
If the number of colors can be changed, use
$colors_num = count($colors);
// ...
'color' => $colors[$loop_counter % $colors_num],
// ...

Instead of hardcoding the max value into your if statement, you can create an ArrayIterator, e.g.
$it = new ArrayIterator($colors);
if ( $orders->have_posts() ){
while ($orders->have_posts()) : $orders->the_post();
//...
if(!$it->valid()){
$it->rewind();
}
$myOrders[] = array( 'name' => $name,
'schedule' => $activiteiten,
'link' => $link,
'color' => $it->current(),
'catering' => $catering,
);
//...
$it->next();
endwhile;
}

$loop_counter++;
if($loop_counter == 6){
$loop_counter = 0;
}
can try this

PHP array function reset() is dedicated for this purpose.
if ($loop_counter == 6) {
reset($colors);
}
This will reset your array pointer to first element.

Related

Search associative array of arrays. How?

My question is how can I search an array built this way? Basically there may be a need to repeat the key and this is what I got so far to maybe solve this. If the price is the same for 2 different items I cannot have 2 keys with the same value.
Please feel free to improve on array layout.
$price_list = array(
1 => array("9.99", "EA_WTRESRVD"),
2 => array("9.99", "EA_WTRESRV")
);
Provided there will never be any duplication of the second column, you can do this:
$search = "EA_WTRESRVD"; //value to search for
$price_list = array(
1 => array("9.99", "EA_WTRESRVD"),
2 => array("9.99", "EA_WTRESRV")
);
$array = array_column($price_list, 0, 1);
echo $array[$search];
I would suggest that if you have a unique product code (SKU), you should use this to index your array.
$products = [
'EA_WTRESRVD' => [
'name' => '...',
'price' => 9.99,
// ...
],
'EA_WTRESRV' => [
'name' => '...',
'price' => 9.99,
// ...
],
];
Then you can access the price of any product by it's SKU.
$price = $products['EA_WTRESRV']['price'];
Here's one way:
<?php
$price_list = [ 1 => array("9.99", "EA_WTRESRVD"),
2 => array("9.99", "EA_WTRESRV")];
$search = "EA_WTRESRV";
foreach ($price_list as $arr) {
if (in_array( $search, $arr )) {
echo $search;
}
}
The foreach iterates over the multidimensional array whose elements are each arrays. Each array is inspected by in_array() for the search term.
However, this is not the only way. If you wish to avoid in_array(), you could also code as follows:
<?php
$price_list = [ 1 => array("9.99", "EA_WTRESRVD"),
2 => array("9.99", "EA_WTRESRV")];
$search = "EA_WTRESRV";
$len = strlen($search);
foreach ($price_list as $arr) {
$val = array_values($arr);
foreach($val as $v) {
if ( ( strpos( $v,$search )) !== false) {
if ( strlen($v) == $len) {
echo "$search is in the price list.\n";
}
}
}
}

adding array in PHP

First, im new in PHP so please bear with me.
I just want to add an array with the foreach loop but I can't.
if($size > 0)
{
$resultArray = array();
foreach($result as $hospital)
{
if($hospital)
{
$temp = array('result' => 'true',
'total' => $size,
'id' => $hospital['id'],
'name' => $hospital['name'],
'address' => $hospital['address'],
'telp' => $hospital['telp']);
$resultArray = array_merge_recursive($resultArray, $temp);
//$resultArray = array_splice($resultArray, $i, 0, $temp);
}
}
$this->response($resultArray, 200);
}
I tried to create a $temp array and merge it to the final result, and finally print that final result ($resultArray) to the response.
The array is successfully merged, but not in the way i want. This is the JSON result :
{"result":["true","true"],"total":[2,2],"id":["1","2"],"name":["test","keyword"],"address":["alamat test","alamat keyword"],"telp":["123456","789"]}
What i want is something like this :
-0 :{
result: "true"
total: 2
id: "1"
name: "test"
address: "alamat test"
telp: "123456"
}
-1 :{
result: "true"
total: 2
id: "2"
name: "test2"
address: "alamat tes 2t"
telp: "789"
}
So the response should be an array with 2 items, and each items has some items.
Please kindly help me, Thanks for your help.
It looks to me like you're trying to append an array, to an array, which can be done quite easily:
$resultArray = array();//outside the loop
//loop
$resultArray[] = array(
'result' => 'true',
'total' => $size,
'id' => $hospital['id'],
'name' => $hospital['name'],
'address' => $hospital['address'],
'telp' => $hospital['telp']
);
Job done. You could also use the array_push function, but that's a function. Functions equal overhead, and should, therefore be avoided (if it doesn't affect code readability). You use array_merge and array_merge_recursive if you want to combine arrays:
$foo = array(
array('bar' => 'zar')
);
$bar = array(
array('car' => 'far')
);
var_dump(
array_merge(
$foo,
$bar
)
);
The effect of array_merge here is comparable to:
foreach ($bar as $subArray)
$foo[] = $subArray;
Im not totally sure how you want your final array to be, but this will put it like $resultArray[0] = array( //temparray ) etc..:
if($size > 0){
$resultArray = array();
$i=0;
foreach($result as $hospital){
if($hospital){
$temp = array('result' => 'true',
'total' => $size,
'id' => $hospital['id'],
'name' => $hospital['name'],
'address' => $hospital['address'],
'telp' => $hospital['telp']);
$resultArray[$i][$temp];
$i++;
}
}
$this->response($resultArray, 200);
}
Replace this -
$resultArray = array_merge_recursive($resultArray, $temp);
With this -
$resultArray[] = $temp;

How to extract an array that has a given structure and which's key => value matches a given value of an mutlidimensional array?

I have an array consisting of many other arrays, which might also consist of other arrays. Its basically like a navigation hierarchy, one menu link can be a menu with sub menus and so on.
The structure of $mainarray is like this:
'childarray1' => array(
'link' => array(
..
'mykey' => 'valueofinterest'
),
'below' => array() of childarrays
),
'childarray2' => array(
'link' => array(
..
'mykey' => 'somevalue'
)
),
'childarray3' => array(
'link' => array(
..
'mykey' => 'someothervalue'
),
'below' => array() of childarrays
)
Each childarray can have 2 direct child keys, 'links' and optionally 'below'. Within links there is always a key 'mykey', which is the only key that I need to check. If a child array has ['links']['mykey'] == 'valueofinterest', I'd like to have this element returned, like $sub = $mainarray['child1']['below']['child11']['below']['childofinterest'].
'below' means that the childarray has childs itself which can also have below arrays (sub menu..).
My hude problem is that the childarray I try to find can be in any other childarrays'S 'below' key, I dont know the depth (its not too deep, though it can vary). I've tried to mess with foreach loops and while loops and combining those, I just cant figure it out how to get the child array. I want to do it like this:
$value = 'xxx';
$sub = return_sub_menu($value);
function return_sub_menu($value) {
$array = $mainarray();
$sub = array();
// find the child array which's ['link']['mykey'] == $value;
// $sub is now something like:
// 'childarray321' => array(
// 'link' => array(
// ..
// 'mykey' => 'xxx'
// ),
// 'below' => array() of childarrays which i NEEED :)
//
// )
return $sub;
}
I've tried to walk recursively but cant figure out how to return the element :(
function recursiveSearch($array, $value){
foreach($array as $sub){
if ($sub['link']['mykey'] == $value)
return $sub ;
if (!empty($sub['below'])){
$returned = recursiveSearch($sub['below'], $value);
if ($returned !== null)
return $returned ;
}
}
return null ;
}
$sub = recursiveSearch($array, "valueofinterest");
//Returns array with ['link']['mykey'] == $value ;
var_dump($sub);
UPDATE V2
Fixed the function, so it works now
Try like this,
if (array_key_exists('keyvalue', $array)) {
$subarray = $array['keyvalue'];
return $subarray;
}
It will return sub array
here it is.
$finalarray = array_map(create_function('$yourarray', 'return $yourarray["arrayindex"];'), $actualarray );

array_push creates new arrays instead of adding

I would like to add a key=>value pair to an existing array depending on an if statement.
But it keeps adding the key=>value pair as a new index.
Here is my code:
foreach ($messageRepo as $oneMessage) {
$calculatedTime = $oneMessage->getTimeToLive();
$creationTime = $oneMessage->getCrdate();
$calculatedTimes = $this->androidService->renderFormat($calculatedTime);
$expiringDate = $creationTime + $calculatedTime;
$ausgabe[] = array(
'Time' => key($calculatedTimes),
'Format' => current($calculatedTimes),
'Title' => $oneMessage->getMessageTitle(),
'Text' => $oneMessage->getMessageText(),
);
if (time() > $expiringDate) {
array_push($ausgabe[]['Expired'], $expiringDate);
} else {
array_push($ausgabe[]['Expiring'], $expiringDate);
}
}
The dump says:
array(60 items)
0 => array(4 items)
Time => 0 (integer)
Format => 'Stunden' (7 chars)
Title => '3 wochen total neu' (18 chars)
Text => 'dfdsfsdf fgdsfgdsgf' (19 chars)
1 => array(1 item)
Expired => NULL
But I want Expired => NULL as field in the original index and not as a new one.
You shouldn't use array_push in this case. Use simple assignment instead. As you don't know the index of the element that you are adding, you can create the new array, set all its values and then add it to the overall array. Something like this:
foreach ($messageRepo as $oneMessage) {
$calculatedTime = $oneMessage->getTimeToLive();
$creationTime = $oneMessage->getCrdate();
$calculatedTimes = $this->androidService->renderFormat($calculatedTime);
$expiringDate = $creationTime + $calculatedTime;
$newval = array(
'Time' => key($calculatedTimes),
'Format' => current($calculatedTimes),
'Title' => $oneMessage->getMessageTitle(),
'Text' => $oneMessage->getMessageText(),
);
if (time() > $expiringDate) {
$newval['Expired'] = $expiringDate;
} else {
$newval['Expiring'] = $expiringDate;
}
$ausgabe[] = $newval;
}
You are using array_push together with the $array[] notation, which does the same thing. The end result is creating a new element and then treating that as an array and putting another new element inside.
You should never have any need to use array_push directly. You should use something like this:
// This is what the new array inside $ausgabe will look like
$newItem = array(
'Time' => key($calculatedTimes),
'Format' => current($calculatedTimes),
'Title' => $oneMessage->getMessageTitle(),
'Text' => $oneMessage->getMessageText(),
);
if (...) {
// conditionally add more elements
$newItem['Expired'] = $expiringDate;
}
// Push the final result into $ausgabe
$ausgabe[] = $newItem;
Inserting the half-baked new array into $ausgabe gives trouble because when you want to add more sub-elements later you don't know the key that refers to the new array. You could find it out dynamically, but that's just too much trouble for no benefit.
Edit your code to:
$i=0;
foreach ($messageRepo as $oneMessage) {
$calculatedTime = $oneMessage->getTimeToLive();
$creationTime = $oneMessage->getCrdate();
$calculatedTimes = $this->androidService->renderFormat($calculatedTime);
$expiringDate = $creationTime + $calculatedTime;
$ausgabe[$i] = array(
'Time' => key($calculatedTimes),
'Format' => current($calculatedTimes),
'Title' => $oneMessage->getMessageTitle(),
'Text' => $oneMessage->getMessageText(),
);
if (time() > $expiringDate) {
$ausgabe[$i]['Expired'] = $expiringDate;
} else {
$ausgabe[$i]['Expired'] = $expiringDate;
}
$i++;
}

A recursive function to sort through parent and child nodes in PHP using a foreach loop on an array

I have a data set stored in an array that references itself with parent-child ids:
id, parent_id, title etc. The top tier has a parent_id of 0, and there can be countless parent-child relationships.
So I'm sorting through this array with a foreach loop within a recursive function to check each array element against its parent element, and I think I've been staring at this method too long.
I do end up with the elements in the correct order, but I can't seem to get my lists nested correctly, which makes me think that the method doesn't really work.
Is this the best route to take?
What can I do to improve and fix this method
Is there another trick that I can apply?
Here is my source:
<div>
<div>Subpages</div>
<ul>
<?php subPages($this->subpages->toArray(), 0) ?>
</ul>
<br>
Add New Subpage
</div>
<?php
function subPages($subpages, $parent){
foreach($subpages as $key => &$page){
$newParent = $page['id'];
//If the current page is the parrent start a new list
if($page['id'] == $parent)
{
//Echo out a new list
echo '<ul>';
echo '<li class="collapsed">';
echo '+';
echo ''.$page['title'].'';
subPages($subpages, $newParent);
echo '</li>';
echo '</ul>';
}
//If the page's parent id matches the parent provided
else if($page['parent_id'] == $parent)
{
//Echo out the link
echo '<li class="collapsed">';
echo '+';
echo ''.$page['title'].'';
//Set the page as the new parent
$newParent = $page['id'];
//Remove page from array
unset($subpages[$key]);
//Check the rest of the array for children
subPages($subpages, $newParent);
echo '</li>';
}
}
}
?>
As always, any assistance is appreciated. Please let me know if something isn't clear.
I doubt that you guys are still looking for a real answer to this, but it might help out others with the same problem. Below is a recursive function to resort an array placing children beneath parents.
$initial = array(
array(
'name' => 'People',
'ID' => 2,
'parent' => 0
),
array(
'name' => 'Paul',
'ID' => 4,
'parent' => 2
),
array(
'name' => 'Liz',
'ID' => 5,
'parent' => 2
),
array(
'name' => 'Comus',
'ID' => 6,
'parent' => 3
),
array(
'name' => 'Mai',
'ID' => 7,
'parent' => 2
),
array(
'name' => 'Titus',
'ID' => 8,
'parent' => 3
),
array(
'name' => 'Adult',
'ID' => 9,
'parent' => 6
),
array(
'name' => 'Puppy',
'ID' => 10,
'parent' => 8
),
array(
'name' => 'Programmers',
'ID' => 11,
'parent' => 4
) ,
array(
'name' => 'Animals',
'ID' => 3,
'parent' => 0
)
);
/*---------------------------------
function parentChildSort_r
$idField = The item's ID identifier (required)
$parentField = The item's parent identifier (required)
$els = The array (required)
$parentID = The parent ID for which to sort (internal)
$result = The result set (internal)
$depth = The depth (internal)
----------------------------------*/
function parentChildSort_r($idField, $parentField, $els, $parentID = 0, &$result = array(), &$depth = 0){
foreach ($els as $key => $value):
if ($value[$parentField] == $parentID){
$value['depth'] = $depth;
array_push($result, $value);
unset($els[$key]);
$oldParent = $parentID;
$parentID = $value[$idField];
$depth++;
parentChildSort_r($idField,$parentField, $els, $parentID, $result, $depth);
$parentID = $oldParent;
$depth--;
}
endforeach;
return $result;
}
$result = parentChildSort_r('ID','parent',$initial);
print '<pre>';
print_r($result);
print '</pre>';
It's a wind down method that removes elements from the original array and places them into result set in the proper order. I made it somewhat generic for you, so it just needs you to tell it what your 'ID' field and 'parent' fields are called. Top level items are required to have a parent_id (however you name it) of 0. I also add a depth marker to each item so that you can format on output.
I will try to help you.
It is possible to compose such relations in one pass:
/**
* Used for "recursive" folding of layout items
* Algorithm of infinite tree (non recursive method)
*
* #param array $items
* #return array
*/
function _foldItems($items) {
$result = array();
foreach ($items as $key => $item) {
$itemName = $item['name'];
if (!isset($item['parent']))
continue;
else {
$parentName = $item['parent']; // it can be either `name` or some `id` of the parent item
if (isset($result[$itemName][$item['sequence']])) {
// Done to eliminate `Warning: Cannot use a scalar value as an array in atLeisure_PropertyImport.class.php`
// Sometimes elements already in the list and have [name] => $count and next line tries to put item in array (item becomes parent)
if ( isset($result[$parentName][$item['parentSequence']]['items'][$itemName]) AND
is_scalar($result[$parentName][$item['parentSequence']]['items'][$itemName])
)
$result[$parentName][$item['parentSequence']]['items'][$itemName] = array();
$result[$parentName][$item['parentSequence']]['items'][$itemName][$item['sequence']] = $result[$itemName][$item['sequence']];
unset($result[$itemName][$item['sequence']]);
} else
$result[$parentName][$item['parentSequence']]['items'][$itemName] = $item['count'];
unset($items[$key]);
} // if //
if (empty($result[$itemName]))
unset($result[$itemName]);
} // foreach //
foreach ($items as $item) { // enumerating rest of the items (single items)
$itemName = $item['itemName'];
if (!isset($result[$itemName]))
$result[$itemName][$item['sequence']] = $item['count'];
}
return $result;
}
Example can be a bit hard to read and to understand because there is really too much code, but I've made this function not so long ago for one project and it seems to be work successfully.
NOTE: It will also work if there are several same items linked to one parent item. It uses item sequence number to avoid aliasing similar values into one.

Categories