1

I want to sort below multilevel array on ascending order of price value.

{
    "pData": [
    {
        "name": "Walmart",
        "address": "Full Address for Walmart",
        "pricing": [{
            "id": "Samsung Galaxy 21M",
            "price": 157.0,
        }],
    },
    {
        "name": "Stop & Shop",
        "address": "Full Address for Stop & Shop",
        "pricing": [{
            "id": "Samsung Galaxy 21M",
            "price": 142.0,
        }],
    },
    {
        "name": "Safeway",
        "address": "Full Address for Safeway",
        "pricing": [{
            "id": "Samsung Galaxy 21M",
            "price": 148.0,
        }],
    }
    ],
    "status ":" ok "
}

I tried below code but giving same result without sorting array on value of price key. I even tried many similar codes from different answers on this site but none of working. So please advise what is wrong with my code or suggest completely different code.

function cmp($a, $b)
{
    //if ($a["price"] == $b["price"]) // Try #1
    if($a["pData"]["pricing"]["price"] == $b["pData"]["pricing"]["price"]) // Try #2
    {
        return 0;
    }
    return ($a["price"] < $b["price"]) ? -1 : 1; // Try #1
    return ($a["pData"]["pricing"]["price"] < $b["pData"]["pricing"]["price"]) ? -1 : 1;
}

usort($result,"cmp");
print_r($result);
0

2 Answers 2

1

You should be pretty close with what you have. You don't need the pData index in your callback, instead pass $result['pData'] to usort.

function cmp($a, $b)
{
    if ($a["pricing"][0]["price"] == $b["pricing"][0]["price"])
    {
        return 0;
    }

    return ($a["pricing"][0]["price"] < $b["pricing"][0]["price"]) ? -1 : 1;
}

usort($result["pData"],"cmp");
print_r($result);

I just noticed that you have an array of objects at the pricing element, so sorting the pData element in its current form will be problematic. You may want to pull all of the pricing elements out into a seperate data structure first and then sort that new structure. Something like this may help you get to a better working solution:

$tmp = array();
foreach ($result["pData"] as $pData) {
    foreach ($pData["pricing"] as $pricing) {
        $tmp[] = array(
            "name" => $pData["name"],
            "address" => $pData["address"],
            "id" => $pricing["id"],
            "price" => $pricing["price"]
        );
    }
}

function cmp($a, $b)
{
    if ($a["price"] == $b["price"])
    {
        return 0;
    }

    return ($a["price"] < $b["price"]) ? -1 : 1;
}

usort($tmp,"cmp");
print_r($tmp);
Sign up to request clarification or add additional context in comments.

Comments

1

You can use spaceship operator <=> also known as three-way comparison operator.

usort($result["pData"], function ($a, $b) {
    return $a["pricing"][0]["price"] <=> $b["pricing"][0]["price"];});

For PHP 7.4 with arrow function.

usort($result["pData"], fn($a, $b) => $a["pricing"][0]["price"] <=> $b["pricing"][0]["price"]);

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.