I'm trying to find a way to check if the value of a given key exists in an array (inside a foreach loop).
For some reason it doesn't really work as expected.
The idea is that I already know the name of the key, but only know part of the correlating value for the key.
I'm trying to do something like this, assuming that I know the key is "exampleKeyName" and its value may or may-not contain "matchValue":
foreach( $array as $key => $value) {
if (stripos($array["exampleKeyName"], 'matchValue') !== false) { echo "matched"; }
}
This returns "illegal string offset".
However, if I do this it works:
foreach( $array as $key => $value) {
if (stripos($value, 'matchValue') !== false) { echo "matched"; }
}
The problem here is that I want to be more specific with the query, and only check if the key is "exampleKeyName".
You can use stripos to check the array value contains in a matching string like this way:
foreach( $array as $key => $value) {
if (stripos($array[$key], 'matchValue') !== false) { echo "matched"; }
}
If you want to check if your regex pattern matches a specific value in your array :
if(preg_match("/^yourpattern$/",$myArray["exampleKeyName"])>0) {
// The value of $myArray["exampleKeyName"] is matched by the regex
}
If you check if the regex matches a key :
foreach($myArray as $key => $value):
if(preg_match("/^yourpattern$/",$key)>0) {
// $key is matched by the regex
}
endforeach;
I hope it helps !
edit : bad english
You're not far off, and there are a few ways of doing this.
In your example code you weren't checking the key but the value in both cases. When doing a for loop like in your second code example you have to change your if statement like so to check against the key:
if (stripos($key, 'matchValue') !== false) { echo "matched"; }
Since I don't know what the application of this is I'll just tell you a few other ways of achieving this and perhaps they will also help simplify the code.
php has a helper function called array_key_exists that checks if the given key or index exists in the array. The result is a boolean value. If you just need to know if the array contains an index or key that is another way of doing this. That would look like this:
if( array_key_exists('matchValue', $array) ) {
print('Key exists');
} else {
print('No key found');
}
There is a good Stack Overflow posting about using preg_grep for regex searching of array keys that may also be helpful if you need to use regular expressions for this.
Related
I have the following problem:
I have an array of arrays with unknown amount of subarrays so my array might look like this:
array('element1'=>array('subelement1'=>'value'
'subelement2'=>array(...),
'element2'=>array('something'=>'this',
'subelement1'=>'awesome'));
Now I want to write a function that is able to replace a value by having it's path in the array, the first parameter is an array that defines the keys to search for. If I want to replace 'value' in the example with 'anothervalue', the function call should look like this:
replace_array(array('element1','subelement1'),'anothervalue');
It should also be able to replace all values on a given level by using null or another placeholder e.g.
replace_array(array(-1, 'subelement1'),'anothervalue');
should replace both 'value' and 'awesome'.
I tried to get it work by using a recursive function and references (one call searches the first array by using the first element in the path variable, and then it calls itself again with the subarray until it has found all occurences defined by the given path).
Is there a smart way to get it done? As my reference idea doesn't seem to work that good.
I can post the code I'm using atm later on.
Thank you.
edit: I updated my answer to also do -1
edit: As -1 is valid for use as an array key, I think you shouldn't use that to mark "all" keys. Arrays themselves however cannot be used as an array key. So in stead of -1 , I have chosen to use an array ([] or array()) to mark "all" keys.
function replace_array(&$original_array, $path, $new_value) {
$cursor =& $original_array;
if (!is_array($path))
return;
while($path) {
$index = array_shift($path);
if (!is_array($cursor) || (!is_array($index) && !isset($cursor[$index])))
return;
if (is_array($index)) {
foreach($cursor as &$child)
replace_array($child, $path, $new_value);
return;
} else {
$cursor =& $cursor[$index];
}
}
$cursor = $new_value;
return;
}
// use like : replace_array($my_array, array("first key", array(), "third key"), "new value");
// or php5.4+ : replace_array($my_array, ["first key", [], "third key"], "new value");
The key in constructing this method lies in passing the array by reference. If you do that, the task becomes quite simple.
It is going to be a recursive method, so the questions to ask should be:
Is this the last recursion?
What key do I have to look for in this level?
array_shift() comes in handy here as you get the first level and at the same moment shorten the $searchPath properly for the next recursion.
function deepReplace($searchPath, $newValue, &$array) {
// ^- reference
//Is this the last recursion?
if (count($searchPath) == 0) {
$array = $newValue;
}
if (!is_array($array))
return;
//What key do I have to look for in this level?
$lookFor = array_shift($searchPath);
//To support all values on given level using NULL
if ($lookFor === null) {
foreach ($array as &$value) {
// ^- reference
deepReplace($searchPath, $newValue, $value);
}
} elseif (array_key_exists($lookFor, $array)) {
deepReplace($searchPath, $newValue, $array[$lookFor]);
}
}
See it work here like
deepReplace(array(null, "subelement1"), "newValue", $data);
deepReplace(array("element1", "subelement1"), "newValue", $data);
<?php
$interests[50] = array('fav_beverages' => "beer");
?>
now i need the index (i.e. 50 or whatever the index may be) from the value beer.
I tried array_search(), array_flip(), in_array(), extract(), list() to get the answer.
please do let me know if I have missed out any tricks for the above functions or any other function I`ve not listed. Answers will be greatly appreciated.
thanks for the replies. But for my disappointment it is still not working. btw I have a large pool of data like "beer");
$interests[50] = array('fav_cuisine' => "arabic");
$interests[50] = array('fav_food' => "hummus"); ?> . my approach was to get the other data like "arablic" and "hummus" from the user input "beer". So my only connection is via the index[50].Do let me know if my approach is wrong and I can access the data through other means.My senior just informed me that I`m not supposed to use loop.
This should work in your case.
$interests[50] = array('fav_beverages' => "beer");
function multi_array_search($needle, $interests){
foreach($interests as $interest){
if (array_search($needle, $interest)){
return array_search($interest, $interests);
break;
}
}
}
echo multi_array_search("beer", $interests);
If your array contains multiple sub-arrays and you don't know which one contains the value beer, then you can simply loop through the arrays, and then through the sub-arrays, to search for the value, and then return the index if it is found:
$needle = 'beer';
foreach ($interests as $index => $arr) {
foreach ($arr as $value) {
if ($value == $needle) {
echo $index;
break;
}
}
}
Demo
I am having a a bit of an issue related to checking a returned array for specific matches.
Here is what I do:
I query a server API and the API returns a printable result using:
print_r($result);
the printed result is:
Array
(
[<html><center>Password_Saved!</center></html>] =>
)
So I thought I could do something like:
function checkResult ($needle, $haystack) { return ( stripos($haystack,$needle) !== false ? TRUE : FALSE); }
if ((checkResult("saved",$result))) {
echo "saved";
} else {
echo "not saved";
}
However, this does not work at all, so I am wondering if you could help me find a way if the $result contains the string saved since I need to know this to perform the next action based on the result.
Your help would be greatly appreciated.
The value you are looking for exists in the array's key instead of value.
As such, you need to be doing your search in the array's keys instead of values.
foreach ($result as $key => $value)
{
if (false !== stripos ($key, "saved"))
{
print "{$key} => Saved";
}
}
it doesn't work because your searching for saved when the value you have in the string is Saved. and you should pass your array key.
if ((checkResult("Saved",array_keys($result)[0]))) {
echo "saved";
} else {
echo "not saved";
}
Read about php preg_grep function
For example:
$needle_pattern = '/search/i'; // i for case insensitive
preg_grep($needle_pattern, $array_haystack);
Also notice that in your code you're mixing "saved" and "Saved" which are different :)
For further reading about this method:
How to search in an array with preg_match?
P.S If your "haystack" is actually the keys, you can switch $array_haystack with array_keys($array_haystack) to get an array of all keys.
can anybody let me know why array_search doesnt works for me? All i want is to search value and and get corresponding key value
for eg if i search wiliam i should get 4.. Its simple but aint working for me
<?php
$fqlResult[0]['uid']='1';
$fqlResult[0]['name']='Jay';
$fqlResult[1]['uid']='2';
$fqlResult[1]['name']='UserName2';
$fqlResult[2]['uid']='3';
$fqlResult[2]['name']='Frances';
$fqlResult[3]['uid']='4';
$fqlResult[3]['name']='William';
for($i=0;$i<count($fqlResult);$i++)
{
$userdbname="'".$fqlResult[$i]['name']."'";
$userdb[$userdbname]="'".$fqlResult[$i]['uid']."'";
}
echo "<pre>";
print_r($userdb);
echo "</pre>";
echo array_search('4', $userdb);
?>
It doesn't work because array_seach searches values and "William" is a key. To complicate things, your values and keys are wrapped in single quotes during the for loop.
You'd want to do something like this:
if ( ! empty($userdb["'William'"]) )
{
// Echoes "'4'"
echo $userdb["'William'"];
}
// To find user ID "'4'"
// Outputs "'William'"
echo array_search("'4'", $userdb);
If you don't want things wrapped in single quotes, you'll need to change your for loop as follows:
for($i=0;$i<count($fqlResult);$i++)
{
$userdbname=$fqlResult[$i]['name'];
$userdb[$userdbname]=$fqlResult[$i]['uid'];
}
if ( ! empty($userdb["William"]) )
{
// Outputs "4" (without the single quotes)
echo $userdb["William"];
}
// To find user ID "4" (without the single quotes)
// Outputs "William"
echo array_search('4', $userdb);
array_search() searches values, not keys.
If you want to check the existence of something that you use as a key in an array, you can just use isset:
if(isset($userdb['William'])) {
echo "$userdb[William] is William's uid!";
}
for($i=0;$i<count($fqlResult);$i++)
{
$userdbname=$fqlResult[$i]['uid'];
$userdb[$userdbname]=$fqlResult[$i]['name'];
}
Change
$userdb[$userdbname]="'".$fqlResult[$i]['uid']."'";
with this
$userdb[$i] = "{$fqlResult[$i]['name']}";
array_search only works with arrays of scalar data. You're trying to search an array of arrays. You can easily search the array yourself:
function search_array_col($array, $col, $val)
{
foreach ($array as $key => $a)
{
if ($a[$col] == $val) return $key;
}
return null;
}
echo search_array_col($fqlResult, 'name', 'William') , "\n";
echo search_array_col($fqlResult, 'uid', '4') , "\n";
Edit: n/m, I misread your code. However, you could still use this to search your original array, so I'll leave the answer for reference.
try this:
foreach($fqlResult as $result)
{
$name = $result["name"];
$uid = $result["uid"];
$userdb[$name] = $uid;
}
then you want to use array_key_exists() to find the key. array_search() only works for searching values, not keys.
$nameExists = array_key_exists("William",$userdb);
You can remove the quotes in the $userdbname="'".$fqlResult[$i]['name']."'";
rewrite it to
$userdbname= $fqlResult[$i]['name'];
I want to loop through an array with foreach to check if a value exists. If the value does exist, I want to delete the element which contains it.
I have the following code:
foreach($display_related_tags as $tag_name) {
if($tag_name == $found_tag['name']) {
// Delete element
}
}
I don't know how to delete the element once the value is found. How do I delete it?
I have to use foreach for this problem. There are probably alternatives to foreach, and you are welcome to share them.
If you also get the key, you can delete that item like this:
foreach ($display_related_tags as $key => $tag_name) {
if($tag_name == $found_tag['name']) {
unset($display_related_tags[$key]);
}
}
A better solution is to use the array_filter function:
$display_related_tags =
array_filter($display_related_tags, function($e) use($found_tag){
return $e != $found_tag['name'];
});
As the php documentation reads:
As foreach relies on the internal array pointer in PHP 5, changing it within the loop may lead to unexpected behavior.
In PHP 7, foreach does not use the internal array pointer.
foreach($display_related_tags as $key => $tag_name)
{
if($tag_name == $found_tag['name'])
unset($display_related_tags[$key];
}
Instead of doing foreach() loop on the array, it would be faster to use array_search() to find the proper key. On small arrays, I would go with foreach for better readibility, but for bigger arrays, or often executed code, this should be a bit more optimal:
$result=array_search($unwantedValue,$array,true);
if($result !== false) {
unset($array[$result]);
}
The strict comparsion operator !== is needed, because array_search() can return 0 as the index of the $unwantedValue.
Also, the above example will remove just the first value $unwantedValue, if the $unwantedValue can occur more then once in the $array, You should use array_keys(), to find all of them:
$result=array_keys($array,$unwantedValue,true)
foreach($result as $key) {
unset($array[$key]);
}
Check http://php.net/manual/en/function.array-search.php for more information.
if you have scenario in which you have to remove more then one values from the foreach array in this case you have to pass value by reference in for each:
I try to explain this scenario:
foreach ($manSkuQty as $man_sku => &$man_qty) {
foreach ($manufacturerSkus as $key1 => $val1) {
// some processing here and unset first loops entries
// here dont include again for next iterations
if(some condition)
unset($manSkuQty[$key1]);
}
}
}
in second loop you want to unset first loops entries dont come again in the iteration for performance purpose or else then unset from memory as well because in memory they present and will come in iterations.
There are already answers which are giving light on how to unset. Rather than repeating code in all your classes make function like below and use it in code whenever required. In business logic, sometimes you don't want to expose some properties. Please see below one liner call to remove
public static function removeKeysFromAssociativeArray($associativeArray, $keysToUnset)
{
if (empty($associativeArray) || empty($keysToUnset))
return array();
foreach ($associativeArray as $key => $arr) {
if (!is_array($arr)) {
continue;
}
foreach ($keysToUnset as $keyToUnset) {
if (array_key_exists($keyToUnset, $arr)) {
unset($arr[$keyToUnset]);
}
}
$associativeArray[$key] = $arr;
}
return $associativeArray;
}
Call like:
removeKeysFromAssociativeArray($arrValues, $keysToRemove);