kate_hudson kate_hudson - 5 months ago 9
JSON Question

Looping through JSON decoded data

I make a call to an API by doing the following

$widgets = json_decode(APIHelper::getWidgetsForDashboards($accessToken, $dashboards), true);


The response gives me an array of data which is quite large. I have made an example of what the response for one of the elements is like here

2 => array:23 [▼
"title" => ""
"type" => "smartLabel"
"options" => array:5 [▼
"title" => true
"data" => array:1 [▼
0 => array:3 [▼
"labelName" => "Label"
"labelValues" => array:1 [▼
0 => "Some Name"
]
]
]
]
]


So the Job I am faced with is getting the labelValues. There are some conditions however. I only want the labelValues for objects which have a type of smartLabel. Now I have a working solution which I will show, I just feel like there is a simpler way to achieve this because my current solution involves a lot of nesting. This is what I have done

$titlesArray = array();

foreach($widgets as $widget) {
if ($widget['type'] == 'smartLabel') {
foreach($widget['options'] as $optionKey => $optionValue) {
if($optionKey == 'data') {
foreach($optionValue as $key => $value) {
if($key == 'labelValues') {
foreach($value as $labelKey => $labelValue) {
if($labelKey == 'labelValues') {
foreach($labelValue as $label) {
$titlesArray[] = array(
$label
);
}
}
}
}
}
}
}
}
}


Is there any way to possibly clean this up?

Thanks

Answer

Yes you can reduce the nesting by only itterating the arrays with unknown (eg the numerical) keys, and using a negative if clause:

$titlesArray = array();

foreach($widgets as $widget) {

    if ($widget['type'] != 'smartLabel') continue;

    foreach($widget['options']['data'] as $dataItem) {
        foreach($dataItem['lableValues'] as $value) {
                    $titleArray[]=$value;
        }
    }
}