Reputation: 484
I am trying to loop through a JSON multidimensional array and get the lowest distance
value for each shop and print it along with the location_id
value.
I can't get any further than what I have here. I've tried a million options by searching through stackoverflow but just can't figure out what I'm doing wrong.
My JSON data is like this:
$json = '{
"shops": [
{
"shop_id": "100",
"locations": [
{ "location_id": "100_1", "distance": "10.3" },
{ "location_id": "100_2", "distance": "15.2" }
]
},
{
"shop_id": "101",
"locations": [
{ "location_id": "101_1", "distance": "19.3" },
{ "location_id": "101_2", "distance": "12.4" }
]
}]
}';
Right now, the code I have is:
// Decode the JSON data
$json_data = json_decode($json,true);
// Do a foreach loop
foreach($json_data['shops'] as $shops){
echo $shops['shop_id'].', ';
// Currently prints:
// 101, 102 ,
// But I need it to print:
// 100_1 -> 10.3, 101_2 -> 12.4
}
I tried putting another foreach loop into the existing one but that just prints a 1
.
How do I achieve that? I can't wrap my head around it. I need the lowest distance
value printed for each of the ['shop_id']['locations']
Upvotes: 0
Views: 919
Reputation: 7485
You can use sub-loops, to try and pick out the lowest distance. Easier to follow the code and to construct a resulting array:
<?php
$json = '{
"shops": [
{
"shop_id": "100",
"locations": [
{ "location_id": "100_1", "distance": "10.3" },
{ "location_id": "100_2", "distance": "15.2" }
]
},
{
"shop_id": "101",
"locations": [
{ "location_id": "101_1", "distance": "19.3" },
{ "location_id": "101_2", "distance": "12.4" }
]
}]
}';
$data = json_decode($json, true);
$min_distances = [];
foreach($data['shops'] as $shop)
{
$distance = null;
foreach($shop['locations'] as $location)
{
if(is_null($distance) || $location['distance'] < $distance)
{
$distance = $location['distance'];
$location_id = $location['location_id'];
}
}
$min_distances[] = [
'shop_id'=>$shop['shop_id'],
'distance'=>$distance,
'location_id'=>$location_id
];
}
var_dump($min_distances);
Output:
array(2) {
[0]=>
array(3) {
["shop_id"]=>
string(3) "100"
["distance"]=>
string(4) "10.3"
["location_id"]=>
string(5) "100_1"
}
[1]=>
array(3) {
["shop_id"]=>
string(3) "101"
["distance"]=>
string(4) "12.4"
["location_id"]=>
string(5) "101_2"
}
}
Upvotes: 0
Reputation: 147176
You can use array_column
to extract all the distances for a particular shop and then use min
on that array to get the lowest value. To also get the location, we then use array_search
to find the minimum key with that value and use that to get the appropriate location_id
for the store:
foreach($json_data['shops'] as $shops) {
$distances = array_column($shops['locations'], 'distance');
$locations = array_column($shops['locations'], 'location_id');
$min = min($distances);
$location = array_search($min, $distances);
echo $locations[$location] . ' -> ' . $min . "\n";
}
Output:
100_1 -> 10.3
101_2 -> 12.4
Update
As @Andreas has pointed out in the comments, we can use the third parameter to array_column
to get an array of distances with their location_id
as the key. We can then sort the array and use current
and key
to get the minimum distance and corresponding location:
foreach($json_data['shops'] as $shops) {
$distances = array_column($shops['locations'], 'distance', 'location_id');
asort($distances);
echo key($distances) . ' -> ' . current($distances) . "\n";
}
Output:
100_1 -> 10.3
101_2 -> 12.4
Upvotes: 5