3

So I am wanting to sort an array depending on what the user selects, I have managed to get it all working (With a little help from you guys) and now I am trying to clean up the code. This is what I've got

//Global Sorting Functions (For Rows to Columns)
//Function to sort up or down
function cmpdwn($a, $b) {
    return strcasecmp($a["Name"], $b["Name"]);
}

function cmpup($a, $b, $c) {
    return strcasecmp($b[$c], $a[$c]);
}

//Name Ordering Function ---------------------------------
function nameorder($data) {
    //If Up sorts Assending if Down Decending
    if ($_POST['Sortby'] == "NameDown") {
        uasort($data, "cmpdwn");
    } else {
        uasort($data, "cmpup");
    }

    $nameorder = array();
    $count = 0;
    while (list($key, $value) = each($data)) {
        $nameorder[$count] = $key;
        $count++;
    }
    return $nameorder;
}

This creates an array for an order to print the data in name order, I will be repeating this for email too and others. What I wanted to do is re-use the "cmp" function by putting more than $a and $b into (i.e. $c = "Name" then I can put in "Email" or what ever // cmpup as example). But to from the little I know is that this function is declaring an argument for uasort and I don't send variables into it. Is there a way to do so or is it a case of re writing the function repeatedly.

2
  • 1
    for the purpose of enhancing your code, I guess codereview.stackexchange.com is better place to ask :) Commented Jun 18, 2014 at 11:00
  • Noted for Next time thanks Commented Jun 18, 2014 at 11:07

2 Answers 2

2

Try to make object

class MyComparator {

    private $key;

    function __construct($key) {
        $this->key = $key;
    }

    function compare($a, $b) {
        return strcasecmp($b[$this->key], $a[$this->key]);
    }

    public function setKey($key) {
        $this->key = $key;
    }
}

And use it

$compararor = new MyComparator("Name");

usort($data, array($compararor, "compare"));


OR in php >= 5.3.0. you can use __invoke() method

class MyComparator {

    private $key;

    function __construct($key) {
        $this->key = $key;
    }

    function __invoke($a, $b) {
        return strcasecmp($b[$this->key], $a[$this->key]);
    }

    public function setKey($key) {
        $this->key = $key;
    }
}

And simple call it with

$compararor = new MyComparator("Name");

usort($data, $compararor);
Sign up to request clarification or add additional context in comments.

Comments

0

try this:

// $a is N-th element, $b is next element and $arguments is array of arguments to use in compare logic
usort($array, function($a, $b) use ($arguments) {
     if($a>$b) return 1;
     if($a<$b) return -1;
     foreach($arguments as $argument) {
        if($a==$argument) {
           // return -1;0;1 as you wish
        }
     }
     return 0;
});

5 Comments

Sorry, so use $arguements to input the part of the array i want to compare i.e. "Name" or "Email" then just use $arguements where i've used "Name"?
Your problem was to pass third or more parameters to sorting function. so in my example I use closure to pass it. it could be anything for example use($someArg, $anotherArg) taken from here: php.net//manual/en/functions.anonymous.php
I am not convinced that this pseudo-code is correctly designed.
@mickmackusa thank You for Your comment, me also after 10 years since 2014, seems like I was giving idea to put sorting logic inside comparator function, I just don't touch it as part of history. Please propose best solution as an answer.
I am afraid I find the question too Unclear to answer. There is no minimal reproducible example.

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.