I'm having trouble understanding how to search a multidimensional associative array with more than one value - I've seen multiple examples of how this can be done, but none of them seem to fit my exact scenario.
I have an array like this:
$locations = array(
ABC => array("loc1","loc2"),
DEF => array("loc2","loc3")
)
Note that 'loc2' is in both nested arrays.
I need to be able to search the array for a value that would match both the key and the value of each nested array using the value of another array that is generated by my application from an API, which looks like this:
Array (
[0] => Array (
[callnumber] => Test 8
[shelvinglocation] => loc1
[availability] => 1
[branch] => ABC
)
)
From this array, if both the branch (ABC) and the shelvinglocation (loc1) are found in the $locations array, then I want to output true.
Here's my code so far:
$instLine = "ABC";
$loc = "loc3";
if (array_key_exists($instLine, $locations)) {
foreach ($locations as $key => $value) {
if (in_array($loc, $value)) {
echo "match found";
} else {
echo "no match";
}
}
The output of this is "match found", because it's not specifically matching the array key to the list of locations, it's just searching all locations. The output should be "no match" because loc3 is found in the DEF array, not the ABC array.
How can I rewrite this so that for each given $instLine/$loc combination, the $loc is only looked for in the array that matches the $instline value?
I feel dumb because I'm sure the answer is simple and in the docs and I've just been using the wrong terminology to search for examples. I appreciate any pointers, even a 'here's the documentation you need, dummy'. :)
Thanks in advance!
$found=false;
foreach ($locations as $key => $value){
if($key == $instLine){
foreach($value as $k=>$v){
if($v == $loc){
$found=true;
}
}
}
}
if($found == true){
echo "match found";
} else {
echo "no match";
}
You should iterate over both arrays and set a boolean value to determine if the value exists or not. Your code is working as expected because you are just checking if the value of $loc exists in one of the arrays in your array (which it does). A conditional check for the matching key is also required
What you can do is store the array that matches the $instline value and then search it separately:
if (array_key_exists($instLine, $locations)) {
$arr = $locations[$instLine];
if (in_array($loc, $arr)) {
echo "match found";
} else {
echo "no match";
}
}
Related
So not a stranger to PHP or arrays even, but never had to deal with multidimensional arrays and its doing my head in.
I have the output of a PHP to a server API and need to pull all the mac address values from the (dst_mac) keys, but only on the occasion the category (catname) keys value for each element is emerging-p2p
The format of the array is like this (intermediate keys and values removed for brevity)
[1] => stdClass Object
(
[_id] => 5c8ed5b2b2302604a9b9c78a
[dst_mac] => 78:8a:20:47:60:1d
[srcipGeo] =>
[dstipGeo] => stdClass Object
(
)
[usgipGeo] => stdClass Object
(
)
[catname] => emerging-p2p
)
Any help much appreciated, i know when im out of my depth!
From your example that is an array with a std class. you can use the empty funtion.
//checks if the first key
if (!empty($array[1]->_id)) {
echo $array[1]->dst_mac;
// or do what you want.
}
This example only applies to one array. use a loop to have this dynamically done.
EDIT: My answer was based on your question. Didn't realize you have to check the catname to be 'emerging-p2p' before you get the mac address?
// loop through the array
foreach ($array as $item) {
// checks for the catname
if ($item->catname === 'emerging-p2p') {
// do what you want if the cat name is correct
echo $item->dst_mac;
}
}
Is this what you want?
for($i =0;$i<count($arr);$i++){
if(isset($arr[$i]['catname']) && $arr[$i]['catname']=='emerging-p2p'){
echo $arr[$i]['dst_mac'];
}
}
If there is only one object that has 'emerging-p2p' cat name:
foreach ($your_list_of_objects as $obj) {
if ($obj->catname == 'emerging-p2p') {
return $obj->dst_mac;
}
}
If there are many:
$result = [];
foreach ($your_list_of_objects as $obj) {
if ($obj->catname == 'emerging-p2p') {
$result[]= $obj->dst_mac;
}
}
return $result;
Use for loop.
for($i =0; $i<=count($arr); $i++){
if(arr[$i]['catname']=='emerging-p2p'){
echo arr[$i]['dst_mac'];
}
}
To fetch all the mac where catname is emerging-p2p
//Assuming $arr has array of objects
$result_array = array_filter($arr, function($obj){
if ($obj->catname == 'emerging-p2p') {
return true;
}
return false;
});
foreach ($result_array as $value) {
echo $value->dst_mac;
}
You can use array_column if you need only mac address on the basis of catname.
$arr = json_decode(json_encode($arr),true); // to cast it as array
$temp = array_column($arr, 'dst_mac', 'catname');
echo $temp['emerging-p2p'];
Working demo.
Have a problem with checking array inside of large array of objects. For example I have
$arr1 = array("a"=>12,"b"=5,"c"=>16);
and I need to check if this array exists inside array like this:
$arr2 = array( array( "a"=>12,"b"=5,"c"=>16),
array("d"=>1,"g"=5,"c"=>16),
array("a"=>12,"c"=5,"e"=>3) );
I have tried in_array(), and it works, but takes a lot of time if I have large $arr2.
Thank you in advance.
P.S. works with PHP 5.6
Instead of your current $arr structure, you'd better have an associative array, where the keys uniquely identify the value.
If you need to search that array several times, you might still save time if you would spend some time to create such associative array from your existing array:
$arr2 = array(
array( "a"=>12,"b"=>5,"c"=>16),
array("d"=>1,"g"=>5,"c"=>16),
array("a"=>12,"c"=>5,"e"=>3)
);
// use key/value pairs, with as key the JSON-encoding of the value
// Note: this will take some time for very large arrays:
foreach ($arr2 as $sub) {
ksort($sub); // need to sort the keys to make sure we can find a match when needed
$hash[json_encode($sub)] = $sub;
}
// function to see whether the value is in the array: this will be fast!
function inHash($hash, $sub) {
ksort($sub);
return isset($hash[json_encode($sub)]);
}
// test
if (inHash($hash, array("d"=>1,"g"=>5,"c"=>16))) {
echo "found";
} else {
echo "not found";
}
Of course, if you could create the original immediately with such keys, then you don't have the overhead of creating it afterwards.
#D.Kurapin simply try with == or === operator(according to you) with foreach() like below:
<?php
$arr1 = array("a"=>12,"b"=>5,"c"=>16);
$arr2 = array( array( "a"=>12,"b"=>5,"c"=>16),
array("d"=>1,"g"=>5,"c"=>16),
array("a"=>12,"c"=>5,"e"=>3) );
$isExist = false;
foreach ($arr2 as $key => $value) {
if($value === $arr1){
$isExist = true;
break;
}
}
if($isExist){
echo "yes found in the array";
}
else{
echo "sorry did not find in the array";
}
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.
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.
I am checking a list of 10 spots, each spot w/ 3 top users to see if a user is in an array before echoing and storing.
foreach($top_10['top_10'] as $top10) //loop each spot
{
$getuser = ltrim($top10['url'], " users/" ); //strip url
if ($usercount < 3) {
if ((array_search($getuser, $array) !== true)) {
echo $getuser;
$array[$c++] = $getuser;
}
else {
echo "duplicate <br /><br />";
}
}
}
The problem I am having is that for every loop, it creates a multi-dimensional array for some reason which only allows array_search to search the current array and not all combined. I am wanting to store everything in the same $array. This is what I see after a print_r($array)
Array ( [0] => 120728 [1] => 205247 ) Array ( [0] => 232123 [1] => 091928 )
There seems to be more to this code. As there are variables being called in it that aren't defined, such as $c, $usercount, etc.. And using array_search with the 2nd parameter of $array if it doesn't exist is not a good idea also. Since it seems like $array is being set within the if statement for this only.
And you don't seem to be using the $top10 value within the foreach loop at all..., why is this?
It would help to see more of the code for me to be able to help you.