Jump to content

Multi-dimensional array issue.


Ghoti
Go to solution Solved by mac_gyver,

Recommended Posts

Hey guys.  In the script below i'm trying to check to see if a name exists in a multi-dimensional array.  If it exists, I increase the quantity field in the array.  If it does not exist, it gets added to the array.  The code below does not work as expected.  The 1st time through, it does not find the name Joe, so it successfully creates an entry for $test[0] with Joe and 1 as the array values.  The 2nd-5th times through it never finds the previous entry, so I end up the same entry 5 times.   

All I have to do to make this exact same code work is to create an entry for the $test array before the for loop.  For example, if I simply add this line to the top of the script it works:

$test[] = array("name"="Steve", "qty" = "1");

What am I missing?  I've tried initializing the array before the loop with $test = array(); but that doesn't do any good.

Thanks for any advice you can offer!  

$search="Joe";
for ($j=1; $j<=5; $j++){  
	if($key = array_search($search, array_column($test, "name"))) {
		echo $test[$key]["name"].' exists in array at key '.$key.". Increasing qty.<br \>";
		$test[$key]["qty"] = $test[$key]["qty"] + 1;
	}
	else {
		echo $search." is not in the array. Adding it!<br />";
		$test[] = array("name"=>$search, "qty"=>"1");
	}		
}

for ($k=0; $k<count($test); $k++){
	echo $test[$k]['name']." x".$test[$k]['qty']."<br />";
}

 

Link to comment
Share on other sites

2 hours ago, Barand said:

Re-structuring your array would simplify.

$test = ['Steve' => 1];

$search = 'Joe';
if (isset($test[$search])) {
    $test[$search]++;
}
else $test[$search] = 1;

 

Thanks, but I don't think this accomplishes my goal.  This is a simplified version, but the basic idea is that new names get added, and existing names increase the qty.  I can't use the names as the keys though, because the actual use is much more complicated than my example here.

Link to comment
Share on other sites

2 hours ago, Barand said:

When defining an array, key/value associations use fat arrows, not equals.

$test[] = array("name" => "Steve", "qty" => "1");
                       ^^                ^^

 

Thanks.  This was just a typo  on my part, sorry.  You can see that I did it that way in the code area.  The question here is, why does adding that initial setting of a bogus array value make my code work?

Edited by Ghoti
Link to comment
Share on other sites

To clarify my question more:

This code:

$search="Joe";
for ($j=1; $j<=5; $j++){  
	if($key = array_search($search, array_column($test, "name"))) {
		echo $test[$key]["name"].' exists in array at key '.$key.". Increasing qty.<br \>";
		$test[$key]["qty"] = $test[$key]["qty"] + 1;
	} else {
		echo $search." is not in the array. Adding it!<br />";
		$test[] = array("name"=>$search, "qty"=>"1");
	}		
}

for ($k=0; $k<count($test); $k++){
	echo $test[$k]['name']." x".$test[$k]['qty']."<br />";
}

Results in this output:
 

Joe is not in the array. Adding it!
Joe is not in the array. Adding it!
Joe is not in the array. Adding it!
Joe is not in the array. Adding it!
Joe is not in the array. Adding it!
Joe x1
Joe x1
Joe x1
Joe x1
Joe x1

As you can see, even though Joe gets added to the array on the first pass, the array search doesn't find it during the next 4 loops.  It just gets added 4 more times, instead of adding to the quantity of the existing entry.

Now, if I initialize the array with some bogus values like this:

$test[] = array("name"=>"Steve", "qty"=>"1");   // THIS IS THE ONLY LINE THAT IS DIFFERENT FROM THE PREVIOUS CODE.

$search="Joe";
for ($j=1; $j<=5; $j++){  
	if($key = array_search($search, array_column($test, "name"))) {
		echo $test[$key]["name"].' exists in array at key '.$key.". Increasing qty.<br \>";
		$test[$key]["qty"] = $test[$key]["qty"] + 1;
	} else {
		echo $search." is not in the array. Adding it!<br />";
		$test[] = array("name"=>$search, "qty"=>"1");
	}		
}

for ($k=0; $k<count($test); $k++){
	echo $test[$k]['name']." x".$test[$k]['qty']."<br />";
}

Now the code works as intended.  Joe is added on the 1st pass, and is found on the next 4 loops.... and we get this output, as intended:

Joe is not in the array. Adding it!
Joe exists in array at key 1. Increasing qty.
Joe exists in array at key 1. Increasing qty.
Joe exists in array at key 1. Increasing qty.
Joe exists in array at key 1. Increasing qty.
Steve x1
Joe x5


I can't figure out why it works if I add initialize the array with the bogus Steve entry.  

Edited by Ghoti
Link to comment
Share on other sites

  • Solution

the reason to use the name as the array index is this allows you to directly test for and access the entry in the array, without needing to search through the entire array. this is the same reason that you index data in a database. this greatly simplifies and speeds up the code/query.

the reason your code doesn't work when the data starts at the zeroth index in the array is because array_search() returns the index if the value is found, but the zero index is a false value in a loose-comparison. array_search() returns an exact false value when the search fails to match a value. to test for a not-found condition, you must test if the returned values is exactly false, e.g. ===false. to test for a found condition, you must if the returned value is not exactly false, e.g. !==false.

Link to comment
Share on other sites

9 hours ago, mac_gyver said:

the reason to use the name as the array index is this allows you to directly test for and access the entry in the array, without needing to search through the entire array. this is the same reason that you index data in a database. this greatly simplifies and speeds up the code/query.

the reason your code doesn't work when the data starts at the zeroth index in the array is because array_search() returns the index if the value is found, but the zero index is a false value in a loose-comparison. array_search() returns an exact false value when the search fails to match a value. to test for a not-found condition, you must test if the returned values is exactly false, e.g. ===false. to test for a found condition, you must if the returned value is not exactly false, e.g. !==false.

This was very helpful.  Thank you!!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.