0

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'
2
  • Hi @adam78 does this answer your question? stackoverflow.com/a/2722213/3218652 Commented Sep 8, 2022 at 8:15
  • 1
    @Simeononon this is PHP, not JavaScript Commented Sep 8, 2022 at 8:21

2 Answers 2

2

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

For those stuck with versions of PHP that don't support anonymous functions, it's simpler just to use a foreach loop over $data['packs']:

function get_price($data, $amount, $measure) {
    foreach ($data['packs'] as $pack) {
        if ($pack['amount'] == $amount && $pack['measure'] == $measure) {
            return $pack['price'];
        }
    }
    return 0;
}
Sign up to request clarification or add additional context in comments.

2 Comments

thanks for the solution. I'm stuck with php 5.2 so I've had to use global variables to pass the parameters for the call back. I'm still getting an error on the following reset($values)['price'] in php 5.2. Do you know how to rewrite this line so that it work in php 5.2?
@adam78 you really should upgrade! PHP5 has been out of support a long time and likely has all sorts of security holes in it. In the meantime though I've edited the answer with a solution that will work on 5.2
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.