0

In python, I have the following which works perfectly well:

list = [('wr', ['A1']), ('wr-qA', ['A3']), ('wr,w', ['A4']), ('wr-mw', ['A2']), ('wrs', ['A6']), ('wrD', ['A8']), ('wrS', ['A7']), ('wr.w', ['A5']), ('=k', ['A10']), ('Dd', ['A9'])]

alphabet = " -,.AjawbpfmnrhHxXsSqkgtTdD=/()[]<>{}'*#I1234567890&@"

Sorted_list = sorted(list, key=lambda (v, k): [alphabet.index(c) for c in v])
print Sorted_list

Output:

[('wr', ['A1']), ('wr-mw', ['A2']), ('wr-qA', ['A3']), ('wr,w', ['A4']), ('wr.w', ['A5']), ('wrs', ['A6']), ('wrS', ['A7']), ('wrD', ['A8']), ('Dd', ['A9']), ('=k', ['A10'])]

How can I do the same in PHP with:

$list = array(
    'wr' => 'A1',
    'wr-qA' => 'A3',
    'wr,w' => 'A4',
    'wr-mw' => 'A2',
    'wrs' => 'A6',
    'wrD' => 'A8',
    'wrS' => 'A7',
    'wr.w' => 'A5',
    '=k' => 'A10',
    'Dd' => 'A9'
);
6
  • What is the array in PHP for? Commented Jun 16, 2011 at 9:40
  • the string used as keys are transcriptions of words in a different writing. Sorting them according to the given alphabet gives you a dictionnary. Commented Jun 16, 2011 at 9:49
  • You are also using a list of tuples in python, but a hash in PHP? Is this intended? Commented Jun 16, 2011 at 9:51
  • Please link the original question that belongs to it. Commented Jun 16, 2011 at 9:52
  • @Yet Another Geek Probably not. He doesn't seem to know PHP too well. Commented Jun 16, 2011 at 9:55

4 Answers 4

4

I don't fully understand your question, but if you need to do custom sorting in PHP you need to use usort or uasort. Probably the second one, as I see you have custom key in your array.

If you're lucky enough and can use PHP 5.3 than you may supply the callback as a closure.

This will be the equivalent in PHP of user sorting. The equivalent of indexOf in PHP would be strpos.

Warning: Take care when comparing the return values of strpos because it may return false if it doesn't find any match. And in PHP false is equal (==) to 0.


About your list structure in PHP. Maybe you need something like this.

$list = array(array('wr', array('A1')), array('wr-qA',array('A3')), ...);

Not sure though.

Sign up to request clarification or add additional context in comments.

4 Comments

OH MY GOD. PHP finally got closures. Ahead of Java, so, second-last, that's an achievement, right?
@Dhaivat Java did not need closures as much as PHP, because of anonymous class declarations, so it is purely syntax. In PHP you had to refer to a function by its name in a string, in which closures is a big step forward.
why are you creating array('A1') and so forth, shoul'nt array('wr', 'A1') be enough?
@Yet Another Geek What I wrote is just a transliteration of his python code. Wether it should be enclosed in an array or be a simple string, or any other format for that matter, is entirely his decision.
1

For the lambda sorting, you can use usort(...) (and strcmp() for comparison)

usort($list, "strcmp"); // PHP function name as a string

Since PHP 5.3 you can also use an anonymous function as a callback parameter

usort($list, function($a, $b) { return strcmp($a, $b) }); 
// Note - callback function must return integer comparison between 2 elements

However, if are sorting by value, you can simply use sort() or if you sort by key, use ksort() (Note that they sort in place and return only a boolean flag)

Comments

0

This is what I came up with. It uses uksort(), which takes a user-defined sorting function and sorts the elements based on their keys (which is what you need as it seems).

The code might need a little tweaking, but I tried it and it works. After calling uksort(), the $list variable will contain the sorted array.

In this code example, I used an Anonymous function as a sorting function, which is available from PHP 5.3, before that, you can use a simple function (for examples, you can check the uksort() reference I linked earlier).

$list = array('wr' => 'A1', 'wr-qA' => 'A3', 'wr,w' => 'A4', 'wr-mw' => 'A2', 'wrs' => 'A6', 'wrD' => 'A8', 'wrS' => 'A7', 'wr.w' => 'A5', '=k' => 'A10', 'Dd' => 'A9');
$alphabet = " -,.AjawbpfmnrhHxXsSqkgtTdD=/()[]<>{}'*#I1234567890&@";

uksort($list, function ($a, $b) use ($alphabet) {
    $shorter=min($a, $b);
    $len=strlen($shorter);
    for ($i=0, $len=strlen($shorter); $i < $len; $i++) {
        $aval=strpos($alphabet, $a[$i]);
        $bval=strpos($alphabet, $b[$i]);
        if ($aval!=$bval) {
            return $aval > $bval ? 1 : -1;
        }
    }
    return $shorter==$b ? 1 : -1;
});

EDIT: I quickly wrote a version without an anonymous function:

$list = array('wr' => 'A1', 'wr-qA' => 'A3', 'wr,w' => 'A4', 'wr-mw' => 'A2', 'wrs' => 'A6', 'wrD' => 'A8', 'wrS' => 'A7', 'wr.w' => 'A5', '=k' => 'A10', 'Dd' => 'A9');

function alphabet_sorter($a, $b) {
    $alphabet = " -,.AjawbpfmnrhHxXsSqkgtTdD=/()[]<>{}'*#I1234567890&@";

    $shorter=min($a, $b);
    $len=strlen($shorter);
    for ($i=0, $len=strlen($shorter); $i < $len; $i++) {
        $aval=strpos($alphabet, $a[$i]);
        $bval=strpos($alphabet, $b[$i]);
        if ($aval!=$bval) {
            return $aval > $bval ? 1 : -1;
        }
    }
    return $shorter==$b ? 1 : -1;
}

uksort($list, 'alphabet_sorter');

3 Comments

I have a problem with the 'use ($alphabet)'. Is this because of my version of php?
@Preys Works fine for me. What is your PHP version? If it is at least 5.3, you should show the code somehow that you're using before calling the uksort (maybe use pastebin.com ).
@Preys That won't support anonymous functions. I will quickly rewrite this for you.
0

Using the exact same uksort() function as my answer to your earlier question, you only need to extend the translation string to use upper and lower case letter for non-space letters in your custom alphabet. I withdrew the space from both translation strings because they would both be in the first position and the translation is pointless.

Code: (Demo)

$trans = [
    "-,.AjawbpfmnrhHxXsSqkgtTdD=/()[]<>{}'*#I1234567890&@",
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
];

$list = [
    'wr' => 'A1',
    'wr-qA' => 'A3',
    'wr,w' => 'A4',
    'wr-mw' => 'A2',
    'wrs' => 'A6',
    'wrD' => 'A8',
    'wrS' => 'A7',
    'wr.w' => 'A5',
    '=k' => 'A10',
    'Dd' => 'A9'
];

uksort(
    $list,
    function ($a, $b) use ($trans) {
        return strtr($a, ...$trans) <=> strtr($b, ...$trans);
    }
);

var_export($list);

Output:

array (
  'wr' => 'A1',
  'wr-mw' => 'A2',
  'wr-qA' => 'A3',
  'wr,w' => 'A4',
  'wr.w' => 'A5',
  'wrs' => 'A6',
  'wrS' => 'A7',
  'wrD' => 'A8',
  'Dd' => 'A9',
  '=k' => 'A10',
)

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.