简体   繁体   中英

Get value of object array

I have the following json:

$data = '{"code":"08261",
          "currency":"EUR", 
          "packs":[ {"amount":0.05,"measure":"g","price":73.0}, 
                    {"amount":0.1,"measure":"g","price":108.0}, 
                    {"amount":0.25,"measure":"g","price":154.0}, 
                    {"amount":0.5,"measure":"g","price":296.0}, 
                    {"amount":1.0,"measure":"g","price":394.0}, 
                    {"amount":2.5,"measure":"g","price":771.0}, 
                    {"amount":5.0,"measure":"g","price":1142.0}, 
                    {"amount":10.0,"measure":"g","price":1693.0}]}'; 

I can get the value of code and currency as follows:

// Option 1: through the use of an array.
$jsonArray = json_decode($data,true);

$code =  $jsonArray['code'];

// Option 2: through the use of an object.
$jsonObj = json_decode($data);

$code = $jsonObj->code;

How can I get the price for the following packs where the:

  1. amount is '1.0' and measure is 'g'
  2. amount is '5.0' and measure is 'g'
  3. amount is '10.0' and measure is 'g'

If you convert the json into nested arrays (passing true to the $associative parameter of json_decode , you can then use array_filter to filter the packs to find the values you want:

$data = '{"code":"08261",
          "currency":"EUR", 
          "packs":[ {"amount":0.05,"measure":"g","price":73.0}, 
                    {"amount":0.1,"measure":"g","price":108.0}, 
                    {"amount":0.25,"measure":"g","price":154.0}, 
                    {"amount":0.5,"measure":"g","price":296.0}, 
                    {"amount":1.0,"measure":"g","price":394.0}, 
                    {"amount":2.5,"measure":"g","price":771.0}, 
                    {"amount":5.0,"measure":"g","price":1142.0}, 
                    {"amount":10.0,"measure":"g","price":1693.0}]}'; 

function get_price($data, $amount, $measure) {
    $values = array_filter($data['packs'], function ($a) use ($measure, $amount) {
        return $a['amount'] == $amount && $a['measure'] == $measure;
    });
    if (count($values)) return reset($values)['price'];
    return 0;
}

$data = json_decode($data, true);

echo get_price($data, 1.0, 'g') . PHP_EOL;
echo get_price($data, 5.0, 'g') . PHP_EOL;
echo get_price($data, 10.0, 'g') . PHP_EOL;

Output:

394
1142
1693

You can use array_filter like this:

$jsonObj = json_decode($data);
$result = array_filter(
    $jsonObj->packs,
    fn($pack) => $pack->amount === 1.0 && $pack->measure === 'g'
);

That uses an arrow function . If you generalize that solution, implementing a function:

function filterPacks($packs, $amount, $measure) {
    return array_filter(
        $packs,
        fn($pack) => $pack->amount === $amount && $pack->measure === $measure
    );
}

$jsonObj = json_decode($data);
print_r(filterPacks($jsonObj->packs, 5.0, 'g'));

According to a comment, you have "to use global variables to pass the parameters for the call back" because you're "stuck with php 5.2". You can do this in PHP 5.2.0:

function filterPacks($packs, $amount, $measure) {
    $filtered = array();
    foreach ($packs as $pack) {
        if ($pack->amount === $amount && $pack->measure === $measure) {
            $filtered []= $pack;
        }
    }
    return $filtered;
}

$jsonObj = json_decode($data);
print_r(filterPacks($jsonObj->packs, 10.0, 'g'));

Notice there are pitfalls when comparing floating points .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM