PHP - Find parent key of array - php

I'm trying to find a way to return the value of an array's parent key.
For example, from the array below I'd like to find out the parent's key where $array['id'] == "0002".
The parent key is obvious because it's defined here (it would be 'products'), but normally it'd be dynamic, hence the problem. The 'id' and value of 'id' is known though.
[0] => Array
(
[data] =>
[id] => 0000
[name] => Swirl
[categories] => Array
(
[0] => Array
(
[id] => 0001
[name] => Whirl
[products] => Array
(
[0] => Array
(
[id] => 0002
[filename] => 1.jpg
)
[1] => Array
(
[id] => 0003
[filename] => 2.jpg
)
)
)
)
)

A little crude recursion, but it should work:
function find_parent($array, $needle, $parent = null) {
foreach ($array as $key => $value) {
if (is_array($value)) {
$pass = $parent;
if (is_string($key)) {
$pass = $key;
}
$found = find_parent($value, $needle, $pass);
if ($found !== false) {
return $found;
}
} else if ($key === 'id' && $value === $needle) {
return $parent;
}
}
return false;
}
$parentkey = find_parent($array, '0002');

Since you have a tree structure either of a BFS or DFS can do it. Since the structure is variable a recursive solution would work well. Simply return a sentinel when you find the value, then return the key in the caller.

function array_to_xml($array, $rootElement = null, $xml = null) {
$_xml = $xml;
if ($_xml === null) {
$_xml = new SimpleXMLElement($rootElement !== null ? $rootElement : '<root/>');
}
$has_int_key = 0;
foreach ($array as $k => $v) {
if (is_array($v)) {
if(is_int($k)){
$this->array_to_xml($v, $k, $_xml->addChild($rootElement));
}
else {
foreach($v as $key=>$value) {
if(is_int($key)) $has_int_key = 1;
}
if ($has_int_key) {
$this->array_to_xml($v, $k, $_xml);
} else {
$this->array_to_xml($v, $k, $_xml->addChild($k));
}
}
}
else {
$_xml->addChild($k, $v);
}
}
return $_xml->asXML();
}

Related

PHP unset array value based on key

I have multidimensional array as follows,
[0] => Array
(
[data] =>
[id] => 0000
[name] => Swirl
[categories] => Array
(
[0] => Array
(
[id] => 0001
[name] => Whirl
[products] => Array
(
[0] => Array
(
[id] => 0002
[filename] => 1.jpg
)
[1] => Array
(
[id] => 0003
[filename] => 2.jpg
)
)
)
)
)
I have used the following function to find keys.
function find_parent($array, $needle, $parent = null) {
foreach ($array as $key => $value) {
if (is_array($value)) {
$pass = $parent;
if (is_string($key)) {
$pass = $key;
}
$found = find_parent($value, $needle, $pass);
if ($found !== false) {
return $found;
}
} else if ($key === $needle) {
return $parent;
}
}
return false;
}
$parentkey = find_parent($array, 'id');
Now i need to unset the products array and replace it with another array.
how to do this.please help.
Thanks,
sarnitha
You can use a recursive function over an array:
function replaceInArray(array &$arr, $needleKey, array $replacement) {
foreach ($arr as $k => $v) {
if ($k === $needleKey) {
$arr[$k] = $replacement;
} else {
if (is_array($v)) {
replaceInArray($arr[$k], $needleKey, $replacement);
}
}
}
}
replaceInArray($sourceArr, 'products', ['id' => '0004', 'filename' => 'new.jpg']);
function replaceInArrayWithKey(array &$arr, $needleKey, array $replacementArray, $replacementKey) {
foreach ($arr as $k => $v) {
if ($k === $needleKey) {
$arr[$replacementKey] = $replacementArray;
unset($arr[$k]);
} else {
if (is_array($v)) {
replaceInArrayWithKey($arr[$k], $needleKey, $replacementArray, $replacementKey);
}
}
}
}
replaceInArrayWithKey($sourceArray, 'products', ['id' => '0004', 'filename' => 'new.jpg'], 'products_new');
You can also try using a built-in recursive iterator - https://www.php.net/manual/en/class.recursivearrayiterator.php

PHP - Get key of Associative Array

I have an array
Array(
[32] => ki
[97] => Array
(
[0] => l$
[1] => ml
[2] => 8e
)
[98] => fp
[99] => #w
[100] => lf
)
if I do array search for example:
echo array_search("fp", $array);
the output will be "98". How can I get the key if im looking for a value inside another array like "ml"? I wanted to get "97" if i search for value "ml".
I don't think there is such function for multi arrays
If you want to do it in a loop try:
foreach($array as $key => $value)
{
if(is_array($value))
{
$subarray = $value;
foreach($subarray as $subvalue)
{
if($subvalue == 'ml')
{
echo $key;
break 2;
}
}
}
else
{
if($value == 'ml')
{
echo $key;
break;
}
}
}
You could write an alternate recursive array_search function like this:
function recursive_array_search($needle, $haystack, $parent_key = null) {
foreach($haystack as $key => $value) {
$current_key = $parent_key ? $parent_key : $key;
if($needle === $value || (is_array($value) && recursive_array_search($needle, $value, $current_key) !== false)) {
return $current_key;
}
}
return false;
}
And call it like echo recursive_array_search("ml", $array);
Based on http://php.net/manual/en/function.array-search.php#91365

php searching in multidimensional array of unknown depth

I try to select the data of an array that was constructed by json_decode().
In principle it is an multiarray of unknown dimension.
First of all, I want to search recursively for a value in this array. As a next step I want to get some other values of the upper dimension. So here is an example:
I search for: "2345"
....
$json[3][6]['journal']['headline']="news"
$json[3][6]['journal']['article']=2345
....
$json[8]['journal']['headline']="weather"
$json[8]['journal']['article']=2345
....
After that I want to get the value of the element headline (returning "news" and "weather")
It might be that the element 2345 can be found in different dimensions!!!
Someone could probably do this with a RecursiveIteratorIterator object, but I personally have a hard time with iterator objects, so here is a fairly robust system:
<?php
// This will traverse an array and find the
// value while storing the base key
class RecurseLocator
{
public static $saved = array();
public static $find;
public static $trigger;
public static function Initialize($find = false)
{
self::$find = $find;
}
public static function Recursive(array $array)
{
foreach($array as $key => $value) {
if(!isset(self::$trigger) || (isset(self::$trigger) && empty(self::$trigger))) {
if(is_numeric($key))
self::$trigger = $key;
}
if(!is_array($value)) {
if($value == self::$find) {
self::$saved[self::$trigger] = $value;
}
}
if(is_array($value)) {
$value = self::Recursive($value);
if(!is_numeric($key))
self::$trigger = "";
}
$return[$key] = $value;
}
return $return;
}
}
// This class will traverse an array searching
// for a specific key or keys
class RecurseSearch
{
public $data;
public $compare;
public function Find($array = '',$find,$recursive = true)
{
$find = (is_array($find))? implode("|",$find):$find;
if(is_array($array)) {
foreach($array as $key => $value) {
if(preg_match("/$find/",$key))
$this->compare[$key] = $value;
if($recursive == true) {
if(!is_array($value)) {
if(preg_match("/$find/",$key)) {
$this->data[$key][] = $value;
}
$array[$key] = $value;
}
else {
if(preg_match("/$find/",$key))
$this->data[$key][] = $this->Find($value,$find);
$array[$key] = $this->Find($value,$find);
}
}
else {
if(preg_match("/$find/",$key))
$this->data[$key] = $value;
}
}
$this->data = (isset($this->data))? $this->data:false;
return $this;
}
}
}
// This function just wraps the RecurseSearch class
function get_key_value($array = array(), $find = array(),$recursive = true)
{
$finder = new RecurseSearch();
return $finder->Find($array,$find,$recursive);
}
USAGE:
$json[3][6]['journal']['headline'] = "news";
$json[3][6]['journal']['article'] = 2345;
$json[8]['journal']['headline'] = "weather";
$json[8]['journal']['article'] = 2345;
$json[4][1]['journal']['headline'] = "news";
$json[4][1]['journal']['article'] = 22245;
$json[5]['journal']['headline'] = "weather";
$json[5]['journal']['article'] = 233345;
// Set the search criteria
RecurseLocator::Initialize(2345);
// Traverse the array looking for value
$arr = RecurseLocator::Recursive($json);
// If found, will be stored here
$iso = RecurseLocator::$saved;
/* $iso looks like:
Array
(
[3] => 2345
[8] => 2345
)
*/
// Loop through the $iso array
foreach($iso as $key => $value) {
// Save to new array your search results
$new[] = get_key_value($json[$key],array("headline","article"),true);
}
/* $new looks like:
Array
(
[0] => RecurseSearch Object
(
[data] => Array
(
[headline] => Array
(
[0] => news
)
[article] => Array
(
[0] => 2345
)
)
[compare] => Array
(
[headline] => news
[article] => 2345
)
)
[1] => RecurseSearch Object
(
[data] => Array
(
[headline] => Array
(
[0] => weather
)
[article] => Array
(
[0] => 2345
)
)
[compare] => Array
(
[headline] => weather
[article] => 2345
)
)
)
*/
?>
Just as a side note, the above class stores multiple found in the [data], and then stores them also in the [compare], however the [compare] will overwrite itself if multiple same-keys are found in one array where as [data] will just keep adding values.
just create a function for compile unknown array. try this
$json[1][6]['journal']['headline']="news";
$json[1][6]['journal']['article']=2345;
$json[3][6]['journal']['headline']="HOT";
$json[3][6]['journal']['article']=2345;
$json[8]['journal']['headline']="weather";
$json[8]['journal']['article']=2345;
$json[10]['journal']['headline']="weather";
$json[10]['journal']['article']=2345;
$GLOBALS['list_scan'] = array();
$result = array();
foreach ($json as $key => $value)
{
if (is_array($value)) {
_compile_scan($key, $value);
}
}
echo "<pre>";
print_r($GLOBALS['list_scan']);
echo "</pre>";
$search = "2345";
$keyword = "article";
$keyFinder = "headline";
foreach ($GLOBALS['list_scan'] as $key => $value)
{
if ($value == $search)
{
$addr = substr($key, 0, -(strlen($keyword))).$keyFinder;
if (!empty($GLOBALS['list_scan'][$addr]))
{
$result[] = $GLOBALS['list_scan'][$addr];
}
}
}
echo "<pre>";
print_r($result);
echo "</pre>";
function _compile_scan($index, $value)
{
$pointer =& $GLOBALS['list_scan'];
foreach ($value as $key => $val)
{
$temp = '';
$temp = $index.'|'.$key;
if (is_array($val))
{
// $pointer[$temp] = $val;
_compile_scan($temp, $val);
}
else $pointer[$temp] = $val;
}
}
output:
Array
(
[1|6|journal|headline] => news
[1|6|journal|article] => 2345
[3|6|journal|headline] => HOT
[3|6|journal|article] => 2345
[8|journal|headline] => weather
[8|journal|article] => 2345
[9|journal|headline] => Others
[9|journal|article] => 234521
)
Array
(
[0] => news
[1] => HOT
[2] => weather
)

search and find several keys in array

public function array_searchh($needle, $haystack) {
foreach ($haystack as $key => $value) {
$current_key = '';
$current_key .= $key;
if ($needle === $value OR (is_array($value) && $this->array_searchh($needle, $value) !== false)) {
return $current_key;
}
}
return false;
}
When I search in array return first key, but I want to search and if there same value return all keys.
[0] => Array ([id] => 1[value] => payamm)
[1] => Array ([id] =>2[value]=>payam)
[2] => Array ([id] => 25[value] => payam)
[3] => Array ([id] => 3[value] => payam)
[4] => Array ([id] => 4[value] => payam)
[5] => Array ([id] => 5[value] => 340)
In above array, I have several "payam" values. When I use above function, I just return the first (found) key but I want all matching keys.
public function array_searchh($needle, $haystack) {
foreach ($haystack as $key => $value) {
$current_key = '';
$current_key .= $key;
if ($needle === $value OR (is_array($value) && $this->array_searchh($needle, $value) !== false)) {
$foundKeys[] = $current_key;
}
}
if (isset($foundKeys)) {
return $foundKeys;
}
return false;
}
This should return an array of all the found keys.
Instead of immediately returning the key, collect all matching keys into an array and return this array at the end of the function.
public function array_searchh($needle, $haystack) {
$returnKeys = array();
foreach ($haystack as $key => $value) {
$current_key = '';
$current_key .= $key;
if ($needle === $value OR (is_array($value) && $this->array_searchh($needle, $value) !== false)) {
$returnKeys[] = $current_key;
}
}
return (count($returnKeys) > 0) ? $returnKeys : false;
}
maybe the array_keys() function would help?

Checking value in an multi-dim array?

My array is like:
Array
(
[0] => Array
(
[id] => 6
[name] => Name1
)
[1] => Array
(
[id] => 7
[name] => Name2
)
)
How can I check any perticular value of name exists in this multi-dimentional array?
function checkName($haystack, $needle) {
foreach($haystack as $hay) {
if($hay['name'] == $needle) {
return true;
}
}
return false;
}
Iterate.
function multi_in_array($name, $array) {
foreach ($array as $sub_array) {
if (in_array($name, $array)) {
return true;
}
}
return false;
}
perhaps you're looking for in_array function?
With that structure, your only option is essentially a linear search:
$found = null;
foreach ($arr as $idx => $elem) {
if ($elem['name'] == $searchName) {
$found = $idx;
}
}
if ($found !== null) {
echo "Found $searchName at $idx.";
}
This function will help you,
<?php
function multi_dim_array_search($array,$col,$val)
{
foreach($array as $elem)
if($elem[$col] == $val)
return true;
return false;
}
$array = array(
array('id' => 1,'name' => 'Name1'),
array('id' => 2,'name' => 'Name2')
);
//usage
var_dump(multi_dim_array_search($array,'name','Name1')); //true
var_dump(multi_dim_array_search($array,'name','Name2')); //true
var_dump(multi_dim_array_search($array,'name','Name3')); //false
?>

Categories