7

The following code lays within a function which itself lays within a class. Its purpose is to avoid having one sorting function per $filter value :

$GLOBAL['filter'] = $filter;
usort($this->data, function($arr1, $arr2) {
    return ($arr1[$GLOBALS['filter']] > $arr2[$GLOBALS['filter']]) ? 1 : -1;
});

My solution works perfectly fine, but I find it rather inelegant. Would somebody have an idea to acheive the same goal without resorting to the $GLOBALS variable ?

Thanks for your propositions

3 Answers 3

26

Since you're using an anonymous function, you can use it as a closure like this:

$filter = <whatever>;
usort($this->data, function($arr1, $arr2) use ($filter) {
    return ($arr1[$filter] > $arr2[$filter]) ? 1 : -1;
});
Sign up to request clarification or add additional context in comments.

Comments

0
   public function sortList($params, $listToSort)
    {
        if (!isset($listToSort) || !isset($params) || count($params) == 0) {
            return $listToSort;
        }
        foreach ($params as $col => $value) {
            $orderFlag = $value == 'asc' ? 1 : -1;
            usort($listToSort, function ($a, $b) use ($orderFlag, $col) {
                return strcmp($a[$col], $b[$col]) * $orderFlag;
            });
        }
    return $listToSort;
}

Above $params is json eg: {name : 'asc', age : 'desc'} and $listToSort is array of array eg: array(array('name': 'Himanshu', age: 22), array('name': 'Steve', age: 35))

Place this code in Utils.php of your project as it is a general solution.

Comments

0

In modern PHP, there are better tools available.

From PHP7, the spaceship operator (<=>) is available to make a 3-way comparison. This is more reliable than a "greater than / less than" 2-way comparison.

From PHP7.4, arrow functions allow more concise syntax and remove the need for use().

Code:

usort($this->data, fn($arr1, $arr2) => $arr1[$filter] <=> $arr2[$filter]);

If value in $filter might not exist as a key in the arrays, then you can use ?? (null coalescing operator) to fallback to a default value.

usort(
    $this->data,
    fn($arr1, $arr2) => ($arr1[$filter] ?? $fallback) <=> ($arr2[$filter] ?? $fallback)
);

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.