Search array path with related values - php

I'm working on a menu system and am working on some complex issues. The menu is generated from a array. This array is included in a pastebin because it's really big. I want to search in the array and get the hierarchical path of the value I'm searching while also getting the values next to the parents you run trough. As I said its quite complex.
In the pastebin is the array and the result I want to function to return:
-->pastebin<--
I tried writing this function quite a few times but always get stuck in the middle.

Here is a function:
function get_item_recursive($id, $menu_array = array())
{
foreach($menu_array as $menu_item)
{
if(isset($menu_item['id']) && $menu_item['id'] == $id)
{
$menu_item['subitems'] = array();
return $menu_item;
}
else
{
if(isset($menu_item['subitems']) && !empty($menu_item['subitems']))
{
$found = get_item_recursive($id, $menu_item['subitems']);
if($found)
{
return $menu_item;
}
}
}
}
return FALSE;
}
I have not tested it, but this is the idea.

You are basically looking for the path to build something like a breadcrumb? You can use a recursive function for that:
function findPath($haystack, $id, $parents = array()) {
foreach ($haystack as $k => $v) {
if ($v['id'] == $id) {
return array_merge($parents, array($v));
} else if (!empty($v['subitems'])) {
unset($v['subitems']);
$return = findPath(
$haystack[$k]['subitems'],
$id,
array_merge($parents, array($v))
);
if ($return) return $return;
}
}
return false;
}
Executing this function like this:
findPath($haystack, 11);
Would return:
Array (
[in-balans] => Array
(
[id] => 2
[slug] => in-balans
[title] => In balans
)
[arbodienstverlening] => Array
(
[id] => 10
[slug] => arbodienstverlening
[title] => Arbodienstverlening
)
[arbo] => Array
(
[id] => 11
[slug] => arbo
[title] => Arbo
[subitems] =>
)
)

Related

how to find if specific value exists in a key, and then extract that array in new array in php

I have the following array:
Array
(
[0] => Array
(
[CODE] => OK
[company_id] => 170647449000
[taxnumber] => 944703420
[name] => SOME NAME
[title] => S.A
)
[1] => Array
(
[CODE] => OK
[company_id] => 17063649000
[taxnumber] => 999033420
[name] => SOME OTHER NAME
[title] => ANOTHER DIFFERENT TITLE
)
)
If the array contain the company_id with the value 17063649000 I need to extract that array (1) in an new array, so I can manipulate it further.
I make numerous code snippets but I am not even close to the solution. I still can not figure out how can I find if the $value (17063649000) exists in the array....not to mention how to extract that specific array (1) from the existing array....
My latest attempt was to modify this and to make it to work, but I am still not managing to make it:
function myfunction($agents, $field, $value)
{
foreach($agents as $key => $agent)
{
if ( $agent[$field] === $value )
return $key;
}
return false;
}
I always get false, even I am sending the value that exists.
Replace return $key with return $agent and operator === with ==.
=== checks type too, it could be reason why it doesn't work.
if your array is $companies then
function getCompany($search_id, $companies) {
foreach($company in $companies) {
if ($companies['company_id'] == $search_id) {
return $company;
}
}
return false;
}
$companies = [...];
$search = 17063649000;
if ($company = getCompany($search, $companies) ) {
// do something with $company
} else {
// not found
}

Compare Array key value with the given name

Hi i am working on some array operations with loop.
I want to compare array key value with the given name.
But i am unable to get exact output.
This is my array :
Array
(
[0] => Array
(
[label] =>
[value] =>
)
[1] => Array
(
[label] => 3M
[value] => 76
)
[2] => Array
(
[label] => Test
[value] => 4
)
[3] => Array
(
[label] => Test1
[value] => 5
)
[4] => Array
(
[label] => Test2
[value] => 6
)
)
This is my varriable which i need to compare : $test_name = "Test2";
Below Code which i have tried :
$details // getting array in this varriable
if($details['label'] == $test_name)
{
return $test_name;
}
else
{
return "NotFound";
}
But every time its returns NotFound.
Not getting what exactly issue.
#Manthan Dave try with array_column and in_array() like below:
<?php
if(in_array($test_name, array_column($details, "label"))){
return $test_name;
}
else
{
return "NotFound";
}
$details is a multidimensional array, but you are trying to access it like a simple array.
You need too loop through it:
foreach ($details as $item) {
if($item['label'] == $test_name)
{
return $test_name;
}
else
{
return "NotFound";
}
}
I hope your array can never contain a label NotFound... :)
You have array inside array try with below,
if($details[4]['label'] == $test_name)
{
return $test_name;
}
else
{
return "NotFound";
}
Although foreach loop should work but if not try as,
for($i=0; $i<count($details); $i++){
if($details[$i]['label'] == $test_name)
{
return $test_name;
}
else
{
return "NotFound";
}
}
Traverse your array like this,
array_walk($array, function($v) use($test_name){echo $v['label'] == $test_name ? $test_name : "NotFound";});
Just use in_array and array_column without use of foreach loop as
if (in_array($test_name,array_column($details, 'label')))
{
return $test_name;
}
else
{
return "NotFound";
}
You need to check only the if condition like below because else meet at first time it will return the "notfound" then it will not execute.
$result = 'NotFound';
foreach ($details as $item) {
if($item['label'] == $test_name)
{
$result = $test_name;
}
}
return $result;
or
$result = 'NotFound';
if (in_array($test_name,array_column($details, 'label')))
{
$result = $test_name;
}
return $result;

PHP: Search and return value from multi-array with Recursive Function

I have a multi-dimensional array of objects (see sample data below). Now I want to search a value (or property) in the data. If the value is found, the function should return the right object and stop searching.
I found three solutions to do this with a recursive function. But nothing works like described above.
The first is my own solution:
public static function getPathForUrl($folderContentDetails, string $url, $result = NULL)
{
foreach($folderContentDetails as $key => $item)
{
if($item->url === $url)
{
$result = $item;
}
elseif($item->elementType === "folder")
{
$result = self::getPathForUrl($item->folderContent, $url, $result);
}
}
return $result;
}
If you call the function like this:
print_r(self::getPathForUrl($data, 'order/abc/alpha');
then it returns the right object. The downside is, that the function searches the whole data and finally returns the result. I did not find a way to stop the function, if a result is found, so its wasting resources.
The second (standard-)solution that you will find in the web, looks like this:
public static function getPathForUrl($folderContentDetails, string $url)
{
foreach($folderContentDetails as $key => $item)
{
if($url === $item->url OR ($item->elementType == "folder" && Folder::getPathForUrl($item->folderContent, $url) !== false))
{
print_r('inner: <br/>'.$item->url);
// prints more then one value, depending on your data, in my case :
// /order/abc/alpha
// /order/abc
// /order
return $item;
}
}
return false;
}
This function stops, if it finds the right value. But for some reason it returns more than one object, and the final object is wrong (see code-comments).
The last solution looks like this:
public static function getPathForUrl($folderContentDetails, string $url)
{
foreach($folderContentDetails as $key => $item)
{
if($item->elementType == "folder" && $item->url != $url)
{
return self::getPathForUrl($item->folderContent, $url);
// iterates only the first sub-folder, then stops
}
elseif($item->url == $url)
{
print_r($item); //nothing, if not found in first sub-folder
return $item; // nothing, if not found in first sub-folder
}
}
return false;
}
If you return the result of the recursive function, then the function goes down to the first nested element and stops there, so it does not go up again to search the other elements.
If you do not return the result, the function searches the whole data but, of course, does not return the right object.
I probably do not understand the concept of recursion properly. Any help is highly welcome.
These are some sample data:
Array
(
[0] => stdClass Object
(
[elementType] => folder
[path] =>
[url] => /getting-started
[folderContent] => Array
(
[0] => stdClass Object
(
[elementType] => file
[path] => \0_getting_started\01-installation.md
[url] => /getting-started/installation
)
[1] => stdClass Object
(
[elementType] => file
[path] => \0_getting_started\02-system-settings.md
[url] => /getting-started/system-settings
)
[2] => stdClass Object
(
[elementType] => file
[path] => \0_getting_started\index.md
[url] => /getting-started/index
)
)
)
[1] => stdClass Object
(
[elementType] => folder
[path] =>
[url] => /order
[folderContent] => Array
(
[0] => stdClass Object
(
[elementType] => folder
[path] => \2_order
[url] => /order/abc
[folderContent] => Array
(
[0] => stdClass Object
(
[elementType] => file
[path] => \2_order\abc\alpha.md
[url] => /order/abc/alpha
)
)
)
)
)
[3] => stdClass Object
(
[elementType] => file
[path] => \index.md
[url] => /index
)
)
Return exits the function so if you want the first result just return it in your condition
public static function getPathForUrl($folderContentDetails, string $url, $result = NULL)
{
foreach($folderContentDetails as $key => $item)
{
if($item->url === $url)
{
return $item;
}
elseif($item->elementType === "folder")
{
$result = self::getPathForUrl($item->folderContent, $url, $result);
}
}
return $result;
}
If you want to stop after a match of value is made; just return inside the condition;
public static function getPathForUrl($folderContentDetails, string $url, $result = NULL)
{
foreach($folderContentDetails as $key => $item)
{
if($url === $item->url)
{
return $item;
}
if("folder" === $item->elementType)
{
return self::getPathForUrl($item->folderContent, $url, $result);
}
}
}
PS: Keeping in mind Best practices for if/return :)

php array multidimensional search for bad words

im trying to search in an array for badwords.
my array looks like:
Array
(
[base] => 2312783821823912
[charset] => utf-8
[Product] => Samsung PD291 Printer
[meta] => Array
(
[description] => fucking nice Printer
[keywords] =>
)
[n2] => Array
(
[w1] => Array
(
[0] => printer
)
[w2] => Array
(
[0] => Menu
[1] => Main menu
[2] => Social
[3] => Speakers
[4] => 2015
[5] => Highlight
[6] => And... Action!
[7] => Short
[8] => Platin
[9] => Gold
[10] => Silber
[11] => Bronze
[12] => partner
)
)
}
I have an badword array like: $bad = array("fuck", "....);
Now im little bit confused what would be the fastest way to scan all values of the first array and return true or false if it contains badwords?
any advice would help ;-)
Thanks!
//edit:
Thanks # everybody...
I will use:
class BadWordFilter {
private static $bad = "/fuck|ass/i";
public static function hasBadWords($input) {
foreach ($input as $element) {
if (is_array($element)) {
if (self::hasBadWords($element)) {
return true;
}
} else {
if (preg_match(self::$bad, $element)) {
return true;
}
}
}
return false;
}
}
I have tested it, and it will be the fastest solutions for my problem ;-))
Thanks everybody
I think the fastest way is to json_encode the array and scan the json string for the bad words.
Not tested but something like this should work:
function badWordsExists($input_array, $blacklist){
$jsonstring = json_encode($input_array);
foreach($blacklist as $string) {
if(strpos($jsonstring, $string) !== false) {
return true;
}
}
return false;
}
Using regex should be faster but this is just an example to give you a idea how it may work.
You can do it with a recursive search which ends its task when a bad word is found. Note, that converting it to json is sub-optimal, since you convert it into a string and then try to find the bad words in the string. It is time-consuming, especially if you have many arrays to check for bad words.
public class BadWordFilter {
private static $bad = array(); //use your array instead
public static function hasBadWords($input) {
foreach ($element in $input) {
if (is_array($element)) {
if (self::hasBadWords($element)) {
return true;
}
} else {
foreach ($bad as $badWord) {
if(strpos($element, $badWord) !== false) {
return true;
}
}
}
}
return false;
}
}
A recursive function is the answer here. The below code will detect any string in at any element of a given array.
<?php
function containsWord($haystack, $badWord)
{
foreach ($haystack as $index => $item) {
if (is_array($item)) {
containsWord($item, $badWord);
} else {
if (strpos($item, $badWord) !== false) {
echo "'$badWord' has been detected in '$item' at index '$index'";
return true;
}
}
}
echo "$badWord is not in the array";
return false;
}
$array = [1 => [4=> 'badword', 5=> 'qw'], 2 => 'b', 3 => 'c'];
containsWord($array, 'bad');
The output of the above code will be:
'bad' has been detected in 'badword' at index '4'
Hope this helps :)

search associative array by value

I'm fetching some JSON from flickrs API. My problem is that the exif data is in different order depending on the camera. So I can't hard-code an array number to get, for instance, the camera model below. Does PHP have any built in methods to search through associative array values and return the matching arrays? In my example below I would like to search for the [label] => Model and get [_content] => NIKON D5100.
Please let me know if you want me to elaborate.
print_r($exif['photo']['exif']);
Result:
Array
(
[0] => Array
(
[tagspace] => IFD0
[tagspaceid] => 0
[tag] => Make
[label] => Make
[raw] => Array
(
[_content] => NIKON CORPORATION
)
)
[1] => Array
(
[tagspace] => IFD0
[tagspaceid] => 0
[tag] => Model
[label] => Model
[raw] => Array
(
[_content] => NIKON D5100
)
)
[2] => Array
(
[tagspace] => IFD0
[tagspaceid] => 0
[tag] => XResolution
[label] => X-Resolution
[raw] => Array
(
[_content] => 240
)
[clean] => Array
(
[_content] => 240 dpi
)
)
$key = array_search('model', array_column($data, 'label'));
In more recent versions of PHP, specifically PHP 5 >= 5.5.0, the function above will work.
To my knowledge there is no such function. There is array_search, but it doesn't quite do what you want.
I think the easiest way would be to write a loop yourself.
function search_exif($exif, $field)
{
foreach ($exif as $data)
{
if ($data['label'] == $field)
return $data['raw']['_content'];
}
}
$camera = search_exif($exif['photo']['exif'], 'model');
$key = array_search('Model', array_map(function($data) {return $data['label'];}, $exif))
The array_map() function sends each value of an array to a user-made function, and returns an array with new values, given by the user-made function. In this case we are returning the label.
The array_search() function search an array for a value and returns the key. (in this case we are searching the returned array from array_map for the label value 'Model')
This would be fairly trivial to implement:
$model = '';
foreach ($exif['photo']['exif'] as $data) {
if ($data['label'] == 'Model') {
$model = $data['raw']['_content'];
break;
}
}
foreach($exif['photo']['exif'] as $row) {
foreach ($row as $k => $v) {
if ($k == "label" AND $v == "Model")
$needle[] = $row["raw"];
}
}
print_r($needle);
The following function, searches in an associative array both for string values and values inside other arrays. For example , given the following array
$array= [ "one" => ["a","b"],
"two" => "c" ];
the following function can find both a,b and c as well
function search_assoc($value, $array){
$result = false;
foreach ( $array as $el){
if (!is_array($el)){
$result = $result||($el==$value);
}
else if (in_array($value,$el))
$result= $result||true;
else $result= $result||false;
}
return $result;
}
$data = [
["name"=>"mostafa","email"=>"mostafa#gmail.com"],
["name"=>"ali","email"=>"ali#gmail.com"],
["name"=>"nader","email"=>"nader#gmail.com"]];
chekFromItem($data,"ali");
function chekFromItem($items,$keyToSearch)
{
$check = false;
foreach($items as $item)
{
foreach($item as $key)
{
if($key == $keyToSearch)
{
$check = true;
}
}
if($check == true)
{break;}
}
return $check;}
As far as I know , PHP does not have in built-in search function for multidimensional array. It has only for indexed and associative array. Therefore you have to write your own search function!!

Categories