{
"ServiceCurrentlyPlaying": {
"fn": "Slideshow-41958.mp4",
"apps": {
"ServiceCurrentlyPlaying": {
"state": "stopped"
}
}
}
}
How would I break anything named ServiceCurrentlyPlaying out of an array? (from json_decode(file, TRUE)) This is probably an easy question to anyone that knows it, but I've been trying to do something that doesn't involve manually hardcoding each array into another empty array (like with a lot of foreach ($outer as $inner) is what I'm doing but having issues since the amount of nesting varies)
Note: I have to deal with around 41958 files that all have different levels of nesting, different amounts and structure, so ..
Result I'd like would be:
{
"fn": "Slideshow-41958.mp4",
"apps": {
"state": "stopped"
}
}
Thanks, very much appreciated.
Not quite optimized maybe, but this is the idea.
$data = json_decode('{ "ServiceCurrentlyPlaying": { "fn": "Slideshow-41958.mp4", "apps": { "ServiceCurrentlyPlaying": { "state": "stopped" } } } }', true);
$modifiedData = breakArray($data);
function breakArray($arr) {
if(is_array($arr) && sizeof($arr)>0) {
$buffer = array();
foreach($arr as $key=>$value) {
if($key==="ServiceCurrentlyPlaying") {
if(is_array($value)) $buffer = array_merge($buffer, breakArray($value));
} else {
$buffer[$key] = (is_array($value) ? breakArray($value) : $value);
}
}
return $buffer;
} else {
return $arr;
}
}
USE
$array=json_decode($jsondata);
$i=0;
foreach($array as $key=>$arr)
{
$out[$i]['fn']=$arr['fn'];
$out[$i]['apps]=$arr['apps']['ServiceCurrentlyPlaying']
$i++;
}
Related
I'm having a trouble. I was trying to make it work for a long time, so I decided to ask for help here.
I have an with some arrays inside it:
$myarray = [
['string1','string2'],
['string3','string4'],
['string5',['string6','string7','string99']],
['string8','string9']
];
I am making a function that search for a s
function searchArray($array,$chave,$id) {
foreach ($array as $key) {
if (is_array($key)) {
if (($key[0] == $chave) && ($key[1] == $id)) {
break;
}
else {
searchArray($key,$chave,$id);
}
}
}
return $key;
}
$result = searchArray($myarray,'string6','string7');
print_r($result);
It was supposed to print ['string6','string7','string99']]
But it it printing the last "key" of the array: ['string8','string9']
The break is not working. After the break, it continue checking the next arrays.
with these modification it returns the expected values:
<?php
$myarray = [
['string1','string2'],
['string3','string4'],
['string5',['string6','string7','string99']],
['string8','string9']
];
function searchArray($array,$chave,$id) {
foreach ($array as $key) {
if (is_array($key)) {
if (($key[0] == $chave) && ($key[1] == $id)) {
return $key;
} else {
$res = searchArray($key,$chave,$id);
if($res !== false) {
return $res;
}
}
}
}
return false;
}
$result = searchArray($myarray,'string6','string7');
print_r($result);
the failure was to break on success. That makes no sense.
You need to return the value on success. If no success return false. Imagine it may happen that the searched values will not been found so it should return false.
So I've got the following function:
function sitesync_empty_vals(&$entity) {
$vals = false;
$entity = (array) $entity;
foreach ($entity as $field) {
if (is_array($field)) {
foreach ($field as $lang) {
foreach ($lang as $item) {
if (isset($item['value'])) {
if (empty($item['value'])) {
unset($field[$lang][$item]);
break;
}
else {
$vals = true;
}
}
}
}
if (!$vals && is_array($lang)) {
watchdog("field", print_r($field, true));
unset($field[$lang]);
}
}
}
}
I keep getting the error Illegal offset type.
I'm not quite understanding why I'd be getting this error - it seems to be related to unsetting the $field[$lang][$item] (I don't get the error when I comment it out), but why would that be? Is it because it's trying to iterate over that item after it is unset? In the case that that particular value is empty, I want to unset the whole $item - this is for data normalization between two different servers, one of which doesn't store any data, and one of which stores the data as a 0.
foreach ($lang as $item) {
^^^^---array
unset($field[$lang][$item]);
^^^^^---using Array as array key
You probably want something more like:
foreach($lang as $lang_key => $item) {
unset($field[$lang_key]....);
instead. And as the comments below have noted, $item is ALSO an array, so you'll want a similar treatment for that as well.
Here is a quote from the PHP Docs:
Arrays and objects can not be used as keys. Doing so will result in a warning: Illegal offset type.
http://www.php.net/manual/en/language.types.array.php
You have to use the keys, not the arrays themselves:
function sitesync_empty_vals(&$entity) {
$vals = false;
$entity = (array) $entity;
foreach ($entity as $field) {
if (is_array($field)) {
foreach ($field as $langKey=>$lang) {
foreach ($lang as $itemKey=>$item) {
if (isset($item['value'])) {
if (empty($item['value'])) {
unset($field[$langKey][$itemKey]);
break;
}
else {
$vals = true;
}
}
}
}
if (!$vals && is_array($lang)) {
watchdog("field", print_r($field, true));
unset($field[$langKey]);
}
}
}
}
The following code uses foreach on an array and if the value is an array it does a for each on the nested array
foreach ($playfull as $a)
{
if (is_array($a))
{
foreach ($a as $b)
{
print($b);
print("<p>");
}
} else {
print($a);
print("<p>");
}
}
This only works if you know that the arrays may only be nested one level deep
If arrays could be nested an unknown number of levels deep how do you achieve the same result? (The desired result being to print the value of every key in every array no matter how deeply nested they are)
You can use array_walk_recursive. Example:
array_walk_recursive($array, function (&$val)
{
print($val);
}
This function is a PHP built in function and it is short.
Use recursive functions (that are functions calling themselves):
function print_array_recursively($a)
{
foreach ($a as $el)
{
if (is_array($el))
{
print_array_recursively($el);
}
else
{
print($el);
}
}
}
This is the way, print_r could do it (see comments).
You want to use recursion, you want to call your printing function in itself, whenever you find an array, click here to see an example
$myArray = array(
"foo",
"bar",
"children" => array(
"biz",
"baz"),
"grandchildren" => array(
"bang" => array(
"pow",
"wow")));
function print_array($playfull)
{
foreach ($playfull as $a)
{
if (is_array($a))
{
print_array($a);
} else {
echo $a;
echo "<p>";
}
}
}
echo "Print Array\n";
print_array($myArray);
You could use a recursive function, but the max depth will be determined by the maximum nesting limit (see this SO question, Increasing nesting functions calls limit, for details about increasing that if you need it)
Here's an example:
$array = array(1,array(2,3,array(4,5)),6,7,8);
function printArray($item)
{
foreach ($item as $a)
{
if (is_array($a))
{
printArray($a);
} else {
print($a);
print("<p>");
}
}
}
printArray($array);
I hope that helps.
Try this -
function array_iterate($arr, $level=0, $maxLevel=0)
{
if (is_array($arr))
{
// unnecessary for this conditional to enclose
// the foreach loop
if ($maxLevel < ++$level)
{ $maxLevel = $level; }
foreach($arr AS $k => $v)
{
// for this to work, the result must be stored
// back into $maxLevel
// FOR TESTING ONLY:
echo("<br>|k=$k|v=$v|level=$level|maxLevel=$maxLevel|");
$maxLevel= array_iterate($v, $level, $maxLevel);
}
$level--;
}
// the conditional that was here caused all kinds
// of problems. so i got rid of it
return($maxLevel);
}
$array[] = 'hi';
$array[] = 'there';
$array[] = 'how';
$array['blobone'][] = 'how';
$array['blobone'][] = 'are';
$array['blobone'][] = 'you';
$array[] = 'this';
$array['this'][] = 'is';
$array['this']['is'][] = 'five';
$array['this']['is']['five'][] = 'levels';
$array['this']['is']['five']['levels'] = 'deep';
$array[] = 'the';
$array[] = 'here';
$var = array_iterate($array);
echo("<br><br><pre>$var");
Not entirely sure how to adequately title this problem, but it entails a need to loop through any array nested within array, of which may also be an element of any other array - and so forth. Initially, I thought it was required for one to tag which arrays haven't yet been looped and which have, to loop through the "base" array completely (albeit it was learned this isn't needed and that PHP somehow does this arbitrarily). The problem seems a little peculiar - the function will find the value nested in the array anywhere if the conditional claus for testing if the value isn't found is omitted, and vice versa. Anyway, the function is as followed:
function loop($arr, $find) {
for($i=0;$i<count($arr);$i++) {
if($arr[$i] == $find) {
print "Found $find";
return true;
} else {
if(is_array($arr[$i])) {
$this->loop($arr[$i], $find);
} else {
print "Couldn't find $find";
return false;
}
}
}
}
Perhaps you should change your code to something like:
var $found = false;
function loop($arr, $find) {
foreach($arr as $k=>$v){
if($find==$v){
$this->found = true;
}elseif(is_array($v)){
$this->loop($v, $find);
}
}
return $this->found;
}
This has been working for me for a while.
function array_search_key( $needle_key, $array ) {
foreach($array AS $key=>$value){
if($key == $needle_key) return $value;
if(is_array($value)){
if( ($result = array_search_key($needle_key,$value)) !== false)
return $result;
}
}
return false;
}
OK, what about a slight modification:
function loop($arr, $find) {
for($i=0;$i<count($arr);$i++) {
if(is_array($arr[$i])) {
$this->loop($arr[$i], $find);
} else {
if($arr[$i] == $find) {
print "Found $find";
return true;
}
}
}
return false;
}
Hmm?
Try this: PHP foreach loop through multidimensional array
I have an json array like given below, what I want is to
parse through the array and get a value for corresponding
key .Eg SubAdministrativeAreaName .I could have parsed it
like .
["AddressDetails"]['Country']['AdministrativeArea'] ['SubAdministrativeArea']['SubAdministrativeAreaName']
but the structure of array is not fixed , it may contain some other
keys within which "SubAdmininstrativeArea" may be enclosed .
What I want is a php function that will search for a particular key
name through multidimensional json array of any depth .
Any help would be appreciated .
"AddressDetails": {
"Accuracy": 6,
"Country": {
"AdministrativeArea": {
"AdministrativeAreaName": "Maharashtra",
"SubAdministrativeArea": {
"SubAdministrativeAreaName": "Parbhani",
"Thoroughfare": {
"ThoroughfareName": "SH217"
}
}
},
"CountryName": "India",
"CountryNameCode": "IN"
}
}
OK, different answer based on comment below:
function array_key_search_deep($needle, $haystack) {
$value = NULL;
if(isset($haystack[$needle])) {
$value = $haystack[$needle];
} else {
foreach($haystack as $node) {
if(is_array($node)) {
$value = array_key_search_deep($needle, $node);
if(!is_null($value)) {
break;
}
}
}
}
return $val;
}
Old Answer
This will allow you to traverse an unknown path in any array tree:
$path = array('AddressDetails', 'Country', 'AdministrativeArea', 'SubAdministrativeArea', 'SubAdministrativeAreaName');
$node = $json_object;
foreach($path as $path_index) {
if(isset($node[$path_index])) {
$node = $node[$path_index];
} else {
$node = NULL;
}
}
echo($node);
Thanks guys , what I made was a a solution like this
I finally found a simple solution myself
For eg) To get "ThoroughfareName" make a call
recursive_array_search($json_array,'ThoroughfareName') ;
function recursive_array_search($arr,$jackpot)
{
foreach ($arr as $key => $value)
{
if(is_array($value))
{
$val=recursive_array_search($value,$jackpot) ;
return $val;
}
else
{
if($key==$jackpot)
return $value;
}
}
}
You could use JSONPath (XPath for JSON)
http://goessner.net/articles/JsonPath/
(with for instance the expression "$..SubAdministrativeAreaName")
EDIT: Haven't tested it, not sure how reliable it is.