recursive array search for key in PHP - php

I am trying to do an array_search to find the associated value pair
I have an array called $saved_data it contains
Array () {
Client_Information_1 => James
Client_Information_2 => Doe
....
}
I need to return the value (1st call -> James .. 2nd call -> Doe .. etc) each time I call it. the problem is it's not returning the value pair back to me. The needle contains the index "Client_Information_1" .
my solution :
function recursive_array_search($saved_forms, $needle)
{
foreach($saved_forms as $key => $value)
{
if ( $saved_forms[$key] === $needle )
return $key;
}
return false;
}
function call in my loop :
$return_field = recursive_array_search($saved_data,$needle);

The $key is what you're searching for and $value is what you want to return (they value at that index)
So the if statement should look like this:
if ( $key === $needle ) {
return $value;
}

Since your function is not recursive at all or does anything else special, this'll do the same thing just fine:
$return_field = isset($saved_data[$needle]) ? $saved_data[$needle] : false;

Related

Compare PHP array value to PART of a string

I'm trying to automate sifting through my online bank statements. Here's a trivial example of what I need.
I have an array of restaurants against which I sort my credit card statements:
$restaurants = array(
array("vendor" => "default",
"type" => "default"
),
array("vendor" => "dunkin",
"type" => "pastry"
),
array("vendor" => "mcdonald",
"type" => "fastfood"
),
array("vendor" => "olive",
"type" => "italian"
)
);
The statement entries themselves can be a rather descriptive string:
$string = "McDonald's Restaurants Incorporated";
I've tried using array_search and in_array, but they seem to do the reverse of what I need, or they need an exact match like in the example below, but it is not what I need:
$result = array_search($string, array_column($restaurants, 'vendor'));
return $restaurants[$result]['type'];
// returns "default" because "McDonald's Restaurants Incorporated" != "mcdonald"
I would like to be able to match the array value "mcdonald" to any string that contains that chunk of it, and then return type "fastfood" for it. Don't worry about handling multiple occurrences.
You'll need a combination of things - a search-in-string method, and for it to be case insensitive.
You can accomplish this with something like this:
/**
* Perform a string-in-string match case insensitively
* #param string $string
* #param array $restaurants
* #return string|false
*/
function findRoughly($string, $restaurants)
{
$out = false;
foreach ($restaurants as $restaurant) {
// Set up the default value
if ($restaurant['type'] == 'default' && !$out) {
$out = $restaurant['type'];
// Stop this repetition only
continue;
}
// Look for a match
if (stripos($string, $restaurant['vendor']) !== false) {
$out = $restaurant['type'];
// Match found, stop looking
break;
}
}
return $out;
}
And use it like so:
$result = findRoughly("McDonald's", $restaurants);
Example here.
I don't think there's a function in PHP that will handle this quite as cleanly as you want. But you can whip up a quick function to loop through the array looking for matches:
$type = call_user_func( function( $restaurants, $string ) {
foreach ( $restaurants as $restaurant ) {
if ( stripos( $string, $restaurant['vendor'] ) !== FALSE ) {
return $restaurant['type'];
}
}
return $restaurant[0]['type'];
}, $restaurants, $string );
If $string is "McDonald's Restaurants Incorporated", then $type will be "fastfood". The above makes the assumption that the first instance in the array is your default return if none of the specified values match.
I just built this as an anonymous function/closure out of convenience, which I usually would to do cleanly enclose something I only plan to run once. But it may be cleaner as a named function in your application.
I took a different (functional) approach by using array_map and array_filter. It's rather compact due to the use of builtin functions, and gets the job done.
// Anonymous function which gets passed to array_map as a callback
// Checks whether or not the vendor is in the $key_string (your restaurant)
$cmp = function ($array) use ($key_string) {
if (stristr($key_string, $array['vendor'])) {
return $array['type'];
}
return "default";
};
function validResult($item) {
return isset($item) && gettype($item)=="string";
}
$key_string = "McDonald's Restaurants Incorporated";
$results = array_map($cmp, $restaurants);
$results = array_pop(array_filter($results, validResult));
I got fixated on the in_array portion of the question. Editing this to use strpos instead.
Try this:
foreach($restaurants as $restaurant)
{
if(strpos($restaurant['vendor'], $string) !== FALSE)
{
return $restaurant['type']; //Or add to an array/do whatever you want with this value.
}
}
http://php.net/manual/en/function.strpos.php

How to write a php function that the input is array and the function finds the lowest number

Hello how can i create a php function that the input is an array and the function finds the lowest number in the array.
This function makes a few assumptions, such as the value being passed in is actually an array with some values in it. You could add some validation for that if you wished...
function findLowest($myArray)
{
$currLowest=$myArray[0];
foreach($myArray as $val)
{
if($val < $currLowest)
{
$currLowest=$val;
}
}
return $currLowest;
}
can be achieved using built in functions or custom functions
$numbers=array( 4 => 40, 3 => 30, 13 => 38 );
function getMin($source = array())
{
//If you don't need your original index for the lowest value
sort($source);
// after sort original index is lost.
return $source[0]
//OR
//If you need your original index for the lowest value
asort($source);
foreach($source as $key => $value)
{
return $value; //ie return key or value that you need.
}
}
Use any one logic from the function.
$numbers=array( 4 => 40, 3 => 30, 13 => 38 );
function getMin($source = array())
{
//If you don't need your original index for the lowest value
sort($source);
// after sort original index is lost.
return $source[0]
//OR
//If you need your original index for the lowest value
asort($source);
foreach($source as $key => $value)
{
return $value; //ie return key or value that you need.
}
}
This helped me. :)

Access Multidimensional Array element with out knowing parent elements

I have function that returns the following multidimensional array. I don't have control of how the array is formed. Im trying to access the 'Result' elements. This issue is, the name of the parent elements constantly changing. The location of the 'Result' element is always the same (as the is the name "Result"). Is it possible to access that element without know the name of the parent elements?
Array
(
[sHeader] => Array
(
[aAction] => ActionHere
)
[sBody] => Array
(
[CreatePropertyResponse] => Array
(
[CreatePropertyResult] => Array
(
[Message] => Successfully completed the operation
[Result] => 0
[TransactionDate] => 2013-05-19T21:54:35.765625Z
[bPropertyId] => 103
)
)
)
)
An easy option to search the array keys/values recursively is to use a recursive iterator; these are built-in classes, part of the Standard PHP Library.
$result = false;
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($iterator as $key => $value) {
if ($key === 'Result') {
$result = $value;
break;
}
}
var_dump($result);
The bonus here is that you could, if you wanted to, check the depth of the Result item ($iterator->getDepth()) in the array structure and/or check one or more ancestor keys ($iterator->getSubIterator(…)->key()).
If the parent elements have only one child, you can solve it by getting the only element given back by array_keys(), and going two levels deep.
Anyway, if your array changes that much, and you systematically have to access a nested property, you have a design issue for sure.
Edit: array_column won't actually work in this case. You could search through each level, recursively, until you find the given key. Something like:
function find_key_value($array, $search_key) {
if (isset($array[$search_key])) return $array[$search_key];
$found = false;
foreach ($array as $key=>$value) {
if (is_array($value)) $found = find_key_value($value, $search_key);
if ($found) return $found;
}
return false;
}
function findkeyval($arr,$key) {
if(isset($arr[$key])) {
return $arr[$key];
}else {
foreach($arr as $a) {
if(is_array($a)) {
$val=findkeyval($a,$key);
if($val) {
return $val;
}
}
}
}
}

PHP OOP Multidimensional Array Search Issue

I have a function
function GetArrKey( $findArr, $key_arr, $depth=0 )
{
if( count($key_arr) <= $depth || !array_key_exists($key_arr[$depth], $findArr) )
return NULL;
else if( count($key_arr) == $depth+1 )
return $findArr[$key_arr[$depth]];
return self::GetArrKey( $findArr[$key_arr[$depth]], $key_arr, $depth+1 );
}
That searches an array and returns the part of the array that matches what I need.
The only problem is it seems to be returning the exact same value. For example, I have this function in a foreach loop
foreach($e as $k => $v) {
$value = GetArrayKey(array,$k);
print_r($value);
}
and it's printing the exact same value 5 times (but the $k that I am using to search for is different each time).
I'm assuming it is because of the return self::GetArrKey but I can't seem to fix it.
Examples...
tweet-19486731414564564
Tweet 1
tweet-19486778435455556
Tweet 1
tweet-19703966855465458
Tweet 1
tweet-19842914654654650
Tweet 1
But it should do
tweet-19486731414564564
Tweet 1
tweet-19486778435455556
Tweet 2
tweet-19703966855465458
Tweet 3
tweet-19842914654654650
Tweet 4
I believe your problem is in the last line of your recursive function:
return self::GetArrKey( $findArr[$key_arr[$depth]], $key_arr, $depth+1 );
This means that the function will be called again, until you hit a base case. The base case will return, and this function does not modify that case. Therefore all calls to the recursive function will return only the result of the base case, which is not what you want in this case because you're looking for a response rather than performing some function recursively.

check is Array empty or not (php)

I am using Cakephp and try to customize the paginator result with some checkboxes .I was pass parameters in URL like this
"http://localhost/myproject2/browses/index/page:2/b.sonic:1/b.hayate:7/b.nouvo:2/b.others:-1/b.all:-2"
and cakephp translate URL to be the array like this
Array
(
[page] => 2
[b.sonic] => 1
[b.hayate] => 7
[b.nouvo] => 2
[b.others] => -1
[b.all] => -2
)
other time when I pass params without checking any checkbox.
"http://localhost/myproject2/browses/index/page:2"
and cakephp translate URL to be the array like this
Array
(
[page] => 2
)
how to simple check if [b.????] is available or not? I can't use !empty() function because array[page] is getting on the way.
If you want to check if a specific item is present, you can use either :
isset()
or array_key_exists()
But if you want to check if there is at least one item which has a key that starts with b. you will not have much choice : you'll have to loop over the array, testing each key.
A possible solution could look like this :
$array = array(
'page' => 'plop',
'b.test' => 150,
'b.glop' => 'huhu',
);
$found_item_b = false;
foreach (array_keys($array) as $key) {
if (strpos($key, 'b.') === 0) {
$found_item_b = true;
break;
}
}
if ($found_item_b) {
echo "there is at least one b.";
}
Another (possibly more fun, but not necessarily more efficient ^^ ) way would be to get the array of items which have a key that starts with b. and use count() on that array :
$array_b = array_filter(array_keys($array), function ($key) {
if (strpos($key, 'b.') === 0) {
return true;
}
return false;
});
echo count($array_b);
If page is always going to be there, you could simply do a count.
if (count($params) == 1) {
echo "There's stuff other than page!";
}
You could be more specific and check page is there and the count is one.
I think this is what you are looking for, the isset function so you would use it like...
if(isset(Array[b.sonic]))
{
//Code here
}

Categories