Please help! I have been staring at this for too long. I have a property of an object that is an array of objects. I want to pass in an object to a method of the parent object and search through that array property for a match, and if one is found return the index. Otherwise, I need it to return -1. For some reason, it is not iterating. If I echo out what should be the $order->product property (where the index is pointing during the loop), it is unchanging. I have dumped the array and I know it contains different values. I can show you a big var dump, but I figured I would first ask if there is a simple error or something else that is obvious to you that I have missed.
public function getItemIndex($prod) {
if (isset($this->orders)){
foreach($this->orders as $key => $order) {
if ($order->product == $prod) { //if I echo this $order->product to the screen, it is unchanging
return $key;
} else { return -1; }
}
}
else {
return -1;
}
}
If anyone has any ideas, I am open to discuss and post more information as needed. Thank you for your time.
You are ALWAYS returning a value on the first iteration, either the $key or -1. Try removing the else statement that you currently have. This will allow you to fully iterate over the entire array.
public function getItemIndex($prod) {
if (isset($this->orders)){
foreach($this->orders as $key => $order) {
if ($order->product == $prod) { //if I echo this $order->product to the screen, it is unchanging
return $key;
}
}
}
return -1;
}
This will ONLY return -1 once it has iterated over everything and found nothing to match. It will still return $key if it finds a match.
Related
So I have a function that currently has a foreach and it works amazing, but I'm being forced to change it to a while loop:
PLEASE NOTE: The developers at my company don't want to use the foreach and they think that a while loop would be more efficient, but I'm not understanding how that would be executed, so I need some help.
So I have the following function ($post_blocks is an array of arrays):
public function parse_block_data(string $block_name, string $selector, $post_id)
{
if (!has_blocks($post_id)) {
return false;
}
$post_blocks = parse_blocks(get_the_content('', false, $post_id));
foreach ($post_blocks as $block) {
if ($block_name != $block['blockName']) {
continue;
}
if (!isset($block['attrs']['id'])) {
return false;
}
if (isset($block['attrs']['data'][$selector])) {
return $block['attrs']['data'][$selector];
} else {
break;
}
}
return false;
}
It uses the parameters to build up an array as shown below:
Output
So I started building a while loop inside the function, but I'm clueless on how to achieve it without using a foreach or if it's even possible, so I replaced the foreach with:
// I get the 9 counts of $post_blocks correctly.
$block = 0;
while ($block < count($post_blocks))
// If the $block_name doesn't match `blockName` value inside the multi-dimensional array, then continue iterating until the end and then return false.
// If ['attrs']['id'] is not set, return false.
// At last, if we have a blockName and a ID and the selector is set, return ['attrs']['data'][$selector]
}
All help will be appreciated! It makes no sense to me, but if someone can assist, I'd be forever grateful!
It's basically the same as your foreach loop, you just set the iteration variable by indexing the array, and increment the index manually.
$block_num = 0;
while ($block_num < count($post_blocks)) {
$block = $post_blocks[$block_num];
if ($block_name == $block['blockName']) {
if (!isset($block['attrs']['id'])) {
return false;
}
if (isset($block['attrs']['data'][$selector])) {
return $block['attrs']['data'][$selector];
} else {
break;
}
}
$block_num++;
}
I'm not sure why your colleagues think this is preferable.
If there's a company coding style they want you to follow, why don't you ask them what it should be?
Scratching my head looking at this render function:
public function render($layout, $echo=false)
{
if ($this->_escape)
{
foreach ($this as $n => &$v)
{
if (0) {
} elseif (is_array($v) or is_object($v)) {
$this->htmlspecialchars_recursive($v);
} elseif (is_scalar($v)) {$v=htmlspecialchars($v,ENT_QUOTES,null,false);}
}
}
if ($echo) { $this->insert($layout); return true;
} else { ob_start(); $this->insert($layout); return ob_get_clean(); }
}
I understand that the ampersand means that we're modifying the contents of the collection (associative array in this case?) that we're iterating over, but what's up with this if (0) business?
There's some sort of implicit iteration stuff going on here, what's this called in PHP?
It's called "this refactor is incomplete".
It appears that there was originally 3 if cases used, and the first one became no longer valid. Instead of just removing it, the author changed it to if(0), which will always evaluate to false.
The correct way would be to modify it to this
if (is_array($v) or is_object($v)) {
$this->htmlspecialchars_recursive($v);
}
elseif (is_scalar($v)) {
$v=htmlspecialchars($v,ENT_QUOTES,null,false);
}
The ampersand in the foreach is the reference symbol. $this is an object, and $n will be the property names and $v will be the property value. Without the & you get a copy of the property value. With the & you get a reference to the property, ie: you are changing the actual property value.
I have a very basic question. It's may very poor question but I just want to clear my confusion.
function check_array($user_value,$array)
{
foreach ($array as $key => $value) {
if($value==$user_value)
{
return true;
}
return false;
}
//return false;
}
Why this function always returning false.
for example If I have $numbers = array(1,2,3). If I match 2 with this array it should return me true else return me false. But why it's returning always false ?
why it's returning always false ?
Try to "execute" this function yourself acting as a computer.
If the first element of array is equal to $user_value, it will return true. If not - it will move futher down the loop and return false.
Probably, you wanted to check all the elements of array for equality. In this case you need to use this:
function check_array($user_value,$array)
{
foreach ($array as $key => $value) {
if($value==$user_value)
{
return true;
}
}
return false;
}
The return false is in the wrong place, it should be where you commented it out but not in the other place it is.
function check_array($user_value,$array)
{
foreach ($array as $key => $value) {
if($value==$user_value)
{
return true;
}
}
return false;
}
If the return is in the other place, it will return false after failing to find your value in the first array cell.
You dont need to create a function for it when php has already have it in_array
you can use it like in a single line
$result = in_array($user_value,$array)
It will return true if the value is found and false if not found.
You need not to loop through the array
You have the return false inside of the loop. That means if the first element isn't a match, it will return false. It won't even check the second element of your array
Your function will be returning false, unless it matches the first value in the array.
This is because at the moment your logic is in the wrong order, and if the first value in the array doesn't match $user_value the function returns false.
You could solve this problem by moving the return false; line of code below the loop.
Now the loop will run through all the values in the array. It will return true if it matches one, and if it has checked all the values and there is no match then it will then return false.
function check_array($user_value,$array)
{
foreach ($array as $key => $value) {
if($value==$user_value) return true;
}
return false;
}
This should clear up the logic mistake in your code. However I up-voted Veerendra's in_array() answer as that means there is no need for any loop, cutting down your code.
I have a question about a recursive PHP function.
I have an array of ID’s and a function, returning an array of „child id’s“ for the given id.
public function getChildId($id) {
…
//do some stuff in db
…
return childids;
}
One childid can have childids, too!
Now, I want to have an recursive function, collecting all the childids.
I have an array with ids like this:
$myIds = array("1111“,"2222“,"3333“,“4444“,…);
and a funktion:
function getAll($myIds) {
}
What I want: I want an array, containing all the id’s (including an unknown level of childids) on the same level of my array. As long as the getChildId($id)-function is returning ID’s…
I started with my function like this:
function getAll($myIds) {
$allIds = $myIds;
foreach($myIds as $mId) {
$childids = getChildId($mId);
foreach($childids as $sId) {
array_push($allIds, $sId);
//here is my problem.
//what do I have to do, to make this function rekursive to
//search for all the childids?
}
}
return $allIds;
}
I tried a lot of things, but nothing worked. Can you help me?
Assuming a flat array as in your example, you simply need to call a function that checks each array element to determine if its an array. If it is, the function calls it itself, if not the array element is appended to a result array. Here's an example:
$foo = array(1,2,3,
array(4,5,
array(6,7,
array(8,9,10)
)
),
11,12
);
$bar = array();
recurse($foo,$bar);
function recurse($a,&$bar){
foreach($a as $e){
if(is_array($e)){
recurse($e,$bar);
}else{
$bar[] = $e;
}
}
}
var_dump($bar);
DEMO
I think this code should do the trick
function getAll($myIds) {
$allIds = Array();
foreach($myIds as $mId) {
array_push($allIds, $mId);
$subids = getSubId($mId);
foreach($subids as $sId) {
$nestedIds = getAll($sId);
$allIds = array_merge($allIds, $nestedIds);
}
}
return $allIds;
}
I'm writing a recursive function to construct a multidimensional array. Basically, the problem is as follows:
function build($term){
$children = array();
foreach ( $term->children() as $child ) {
$children[] = build($child);
}
if(!count($children)){
return $term->text();
} else {
return $term->text() => $children; //obviously, this doesn't work
}
}
Thoughts? I know I could rewrite the structure of the function to make it work, but it seems like that should be unnecessary.
function build($term){
$children = array();
foreach ( $term->children() as $child ) {
$children += build($child);
}
if(!count($children)){
return $term->text();
} else {
return array($term->text() => $children); //obviously, this doesn't work
}
}
From what i understand of the question this is what it should look like.
Appending the recursion and returning an array.
Edit: as an aside you might be better off returning an array even if count($children) ==0, this would get all of your types inline. else you may get all sorts of errors down the line:
if(!count($children)){
return array($term->text() => null);
An array is the only key-value pair container PHP has to offer. So you HAVE to use an array if you want your function (may it be recursive or not) to return a key-value pair.
return array($term->text() => $children);
You could return it like this:
return array($term->text() => $children);
Although it's not what you asked. I think you cannot do this without rewriting parts of your function, one way or another.