Custom sorting keys in array using self-created alphabet
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'
);
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.
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)
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');
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',
)
精彩评论