0

I have a JSON response shown as below. an example of the print_r result is shown below

(
[0] => stdClass Object
(
    [name] => Venezuela (Bolivarian Republic of)
    [topLevelDomain] => Array
        (
            [0] => .ve
        )

    [alpha2Code] => VE
    [alpha3Code] => VEN
    [callingCodes] => Array
        (
            [0] => 58
        )

    [capital] => Caracas
    [cioc] => VEN
),
[1] => stdClass Object
(
    [name] => Venezuela (Bolivarian Republic of)
    [topLevelDomain] => Array
        (
            [0] => .ve
        )

    [alpha2Code] => VE
    [alpha3Code] => VEN
    [callingCodes] => Array
        (
            [0] => 58
        )

    [capital] => Caracas
    [cioc] => VEN
),
[2] => stdClass Object
(
    [name] => Venezuela (Bolivarian Republic of)
    [topLevelDomain] => Array
        (
            [0] => .ve
        )

    [alpha2Code] => VE
    [alpha3Code] => VEN
    [callingCodes] => Array
        (
            [0] => 58
        )

    [capital] => Caracas
    [cioc] => VEN
),
....
)

I want to extract only names from the response.

should I use a loop through the array and extract every name from every object in the array and push it in the array or Should I use the following code?

$language = array_map(function($object)
{
    return $object->name; 
}, $jsonReponse); 

Which would be the best choice and why?

Rafay Hassan
  • 740
  • 8
  • 23
  • I guess you should go with array_map() way it seems more cleaner and concise code – A l w a y s S u n n y Dec 18 '18 at 15:49
  • @Curious_MInd, how about performance and is there another way to achieve the same result? – Rafay Hassan Dec 18 '18 at 15:50
  • 1
    You can also use `array_column` for this. Someone posted an answer with that and deleted it for some reason, but it should work as well. They're all about the same, it's really just whichever you prefer. – Don't Panic Dec 18 '18 at 16:46
  • 1
    There is no general way of doing that. If you perform the request on your own, the probably best approach on huge responses could be to request into a temporary file and use some filtering JSON file parser without loading the entire content into memory. Best would be a callback on each occurrence and processing the small piece of data immediately. (Could be achieved in a loop as well.) – Pinke Helga Dec 19 '18 at 11:03
  • 1
    You did not mention if you focus on a high performant way or on lightweight resource consumption or whatever. – Pinke Helga Dec 19 '18 at 11:10
  • If you ask for "best", you need to define by what measure, otherwise it's just asking for opinions, which would be off-topic. Anyhow, best way is not to build an array at all but yield the different elements for further consumption. – Ulrich Eckhardt Dec 26 '18 at 17:25

3 Answers3

1

As per my research you should use foreach() to extract attribute,

while processing huge array of million records foreach is way faster then array_map()

  • Foreach: 0.7 sec
  • Map on function name: 1.2 sec

For more information follow this link.

Tech Kid
  • 577
  • 2
  • 7
  • 19
0

I would just do it with a simple foreach loop:

$nameArr = [];
$arr = json_decode($theObject);

foreach ($arr as $name) {
    array_push($nameArr, $name->name);
}
prafferty
  • 101
  • 8
0

I used this script, generating an array/json with 500,000 registers:

<?php
ini_set('memory_limit', '-1');
set_time_limit(0);

for ($i = 0; $i < 500000; $i++) {
    $response[] = [
        'name' => uniqid(),
        'topLevelDomain' => ['ve'],
        'alpha2Code' => 'VE',
        'alpha3Code' => 'VEN',
        'callingCodes' => [58],
        'capital' => 'Caracas',
        'cioc' => 'VEN',
    ];
}
$response = json_encode($response);

//for
$time = microtime(true);
$data = json_decode($response);
$namesFor = [];
for($i = 0, $c = count($data); $i < $c; $i++) {
    $namesFor[] = $data[$i]->name;
}

echo "<br/> Time with for loop: ";
echo microtime(true) - $time;

//array_column
$time = microtime(true);
$data = json_decode($response, true);
$namesArrayColumn = array_column($data, 'name');

echo "<br/> Time with array_column: ";
echo microtime(true) - $time;

//foreach
$time = microtime(true);
$data = json_decode($response);
$namesForeach = [];
foreach($data as $d) {
    $namesForeach[] = $d->name;
}

echo "<br/> Time with foreach: ";
echo microtime(true) - $time;

//array_map
$time = microtime(true);
$data = json_decode($response);
$namesArrayMap = [];
$namesArrayMap = array_map(function($d) {
    return $d->name;
}, $data);

echo "<br/> Time with array_map: ";
echo microtime(true) - $time;

And the output is

Time with for loop: 2.0891849994659

Time with array_column: 7.5789909362793

Time with foreach: 6.3916020393372

Time with array_map: 7.6288249492645

So, for is the fastest, foreach, array_column and array_map methods are much slower. But, running with 100,000 registers, the difference was minimum:

Time with for loop: 0.40081810951233

Time with array_column: 0.40819096565247

Time with foreach: 0.44123411178589

Time with array_map: 0.58325409889221

Anyway, go with for that will be faster always.

Community
  • 1
  • 1
Felippe Duarte
  • 14,901
  • 2
  • 25
  • 29