1

I'm using the following code to get the distance between location.

<?php
function curl_request($sURL,$sQueryString=null)
{
        $cURL=curl_init();
        curl_setopt($cURL,CURLOPT_URL,$sURL.'?'.$sQueryString);
        curl_setopt($cURL,CURLOPT_RETURNTRANSFER, TRUE);
        $cResponse=trim(curl_exec($cURL));
        curl_close($cURL);
        return $cResponse;
}

$sResponse=curl_request('http://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=London&destinations=Southend-on-sea|Westcliff-on-sea|Leigh-on-sea|leeds&mode=driving&language=en&sensor=false');
$oJSON=json_decode($sResponse);
if ($oJSON->status=='OK')
        $fDistanceInMiles=(float)preg_replace('/[^\d\.]/','',$oJSON->rows[0]->elements[0]->distance->text);
else
        $fDistanceInMiles=0;

echo 'Distance in Miles: '.$fDistanceInMiles.PHP_EOL;

?>

-

This will only get the first value in the JSON response because of this:

$fDistanceInMiles=(float)preg_replace('/[^\d\.]/','',$oJSON->rows[0]->elements[0]->distance->text);

-

The JSON looks like this:

{
   "destination_addresses" : [
      "Southend-on-Sea, UK",
      "Westcliff-on-Sea, Southend-on-Sea, UK",
      "Leigh-on-Sea SS9, UK",
      "Leeds, UK"
   ],
   "origin_addresses" : [ "London, UK" ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "42.0 mi",
                  "value" : 67669
               },
               "duration" : {
                  "text" : "1 hour 14 mins",
                  "value" : 4464
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "42.7 mi",
                  "value" : 68723
               },
               "duration" : {
                  "text" : "1 hour 17 mins",
                  "value" : 4646
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "40.1 mi",
                  "value" : 64508
               },
               "duration" : {
                  "text" : "1 hour 10 mins",
                  "value" : 4225
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "195 mi",
                  "value" : 313043
               },
               "duration" : {
                  "text" : "3 hours 39 mins",
                  "value" : 13133
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}

So when i run my code, I get this printed on my page:

Distance in Miles: 42 

But what I need is to print out the highest number. So it should be like this:

Distance in Miles: 195

Could someone please advise on this?

Thanks in advance.

David Hope
  • 1,426
  • 4
  • 21
  • 50

5 Answers5

3

With array_column() you can extract all the distance arrays and then build a lookup with text as the key and value as the value:

$array = json_decode($json, true);
$dist  = array_column(array_column($array['rows'][0]['elements'], 'distance'),
                                   'value', 'text');

Then just compute the max(), find it and outpout the key:

echo array_search(max($dist), $dist);
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
  • Neat. I suppose you could sort/reverse sort and grab the appropriate element too right? – Matt Jun 14 '17 at 20:45
  • This does what I need to do but why Can't i remove the "mi" ? I tried this: $dist = preg_replace('mi','',$dist); echo array_search(max($dist), $dist); – David Hope Jun 14 '17 at 22:15
  • You need to replace on the return of `array_search()`, but you could take `value` which is meters and divide by `1609.34` to get miles. Or cast to a float `echo (float)array_search(max($dist), $dist);` – AbraCadaver Jun 15 '17 at 14:56
1

For this, you can collect all text, (try using array_column()) keys in an array then find maximum value using max()

Shobi
  • 10,374
  • 6
  • 46
  • 82
  • 2
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/16424047) – Derek Pollard Jun 15 '17 at 03:53
  • Thanks, @Derek for your concern – Shobi Jun 16 '17 at 09:15
1

Here's how you'd do it with array reduce:

<?php

$json = '{
   "destination_addresses" : [
      "Southend-on-Sea, UK",
      "Westcliff-on-Sea, Southend-on-Sea, UK",
      "Leigh-on-Sea SS9, UK",
      "Leeds, UK"
   ],
   "origin_addresses" : [ "London, UK" ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "42.0 mi",
                  "value" : 67669
               },
               "duration" : {
                  "text" : "1 hour 14 mins",
                  "value" : 4464
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "42.7 mi",
                  "value" : 68723
               },
               "duration" : {
                  "text" : "1 hour 17 mins",
                  "value" : 4646
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "40.1 mi",
                  "value" : 64508
               },
               "duration" : {
                  "text" : "1 hour 10 mins",
                  "value" : 4225
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "195 mi",
                  "value" : 313043
               },
               "duration" : {
                  "text" : "3 hours 39 mins",
                  "value" : 13133
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}';

$maxDistance = array_reduce(json_decode($json, true)["rows"][0]["elements"], function($accumulator, $item){
   return ($item['distance']['value'] > $accumulator) ? $item['distance']['value'] : $accumulator;
}, 0);


var_dump($maxDistance);

Yields:

int(313043)

Here's the same code without the unnecessary conversion to an object:

$distance = array_reduce(json_decode($json)->rows[0]->elements, 
function($accumulator, $item){
    return ($item->distance->value > $accumulator) ? $item->distance->value : $accumulator;
}, 0);

If you didn't want to reconvert to miles, you could do the reduce on the float value of the text field instead.

http://sandbox.onlinephpfunctions.com/code/37176c07b7fc46a713b275e2d3326444b970de1a

My guess is that this is the most performant way to do it if you have a large array.

Matt
  • 5,315
  • 1
  • 30
  • 57
1

I don't know if this is the simpler way, but give this a try.

do something like this before printing in the screen.

$lenght_elements=sizeof($oJSON->rows[0])
$array_elements=array();
for($i=0;$i<$lenght_elements;$i++){
$fDistanceInMiles=(float)preg_replace('/[^\d\.]/','',$oJSON->rows[0]->elements[$i]->distance->text);
array_push($array_elements,$fDistanceInMiles);
}

$max_value=max($array_elements); 

echo echo 'Distance in Miles: '.$max_value; //this should print the highest value

NOTE: if you need to run through the rows too, you could use another loop, you'll get your result anyway.

1

Keep it simple.

// get all elements
$elements = json_decode($oJSON)->rows[0]->elements;

// get all the distances
// array_map() is useful here b/c there is a 1-1 correspondence between an element and its distance
$distances = array_map(function ($element) {
    // convert distance to numeric value to ensure that we are only working with numbers (and not strings)
    return (float) preg_replace('/[^\d\.]/','', $element->distance->text);
}, $elements);

// get the maximum value
echo 'Distance in Miles: ' . max($distances);
Mikey
  • 6,728
  • 4
  • 22
  • 45