我希望能在PHP中对字符串进行排序,首先应该根据子字符串的第一个字母进行匹配,然后再根据整个字符串的每个字母进行匹配。
例如,如果有人搜索“do”,并且列表包含:
Adolf
Doe
Done
结果应该是:
Doe
Done
Adolf
使用常规的sort($array, SORT_STRING)
或类似方法无法解决此问题,Adolf会排在其他人之前。
有没有什么好的办法可以解决这个问题呢?
我希望能在PHP中对字符串进行排序,首先应该根据子字符串的第一个字母进行匹配,然后再根据整个字符串的每个字母进行匹配。
例如,如果有人搜索“do”,并且列表包含:
Adolf
Doe
Done
结果应该是:
Doe
Done
Adolf
使用常规的sort($array, SORT_STRING)
或类似方法无法解决此问题,Adolf会排在其他人之前。
有没有什么好的办法可以解决这个问题呢?
usort(数组, 回调函数)
可以通过回调函数来进行排序。
示例(类似于以下内容,未尝试过)
usort($list, function($a, $b) {
$posa = strpos(tolower($a), 'do');
$posb = strpos(tolower($b), 'do');
if($posa != 0 && $posb != 0)return strcmp($a, $b);
if($posa == 0 && $posb == 0)return strcmp($a, $b);
if($posa == 0 && $posb != 0)return -1;
if($posa != 0 && $posb == 0)return 1;
});
usort()
内进行的比较次数,这可能会变得相当繁重 :) - Ja͢ckstripos()
的输出,因此你在节省CPU时间的同时增加了内存消耗。对于大型列表,肯定值得对这两种风格进行基准测试。对于小型列表,差异将是无关紧要的。 - Matthew<?php
$list = ['Adolf', 'Doe', 'Done'];
function searchFunc($needle)
{
return function ($a, $b) use ($needle)
{
$a_pos = stripos($a, $needle);
$b_pos = stripos($b, $needle);
# if needle is found in only one of the two strings, sort by that one
if ($a_pos === false && $b_pos !== false) return 1;
if ($a_pos !== false && $b_pos === false) return -1;
# if the positions differ, sort by the first one
$diff = $a_pos - $b_pos;
# alternatively: $diff = ($b_pos === 0) - ($a_pos === 0)
if ($diff) return $diff;
# else sort by natural case
return strcasecmp($a, $b);
};
}
usort($list, searchFunc('do'));
var_dump($list);
输出:
array(3) {
[0] =>
string(3) "Doe"
[1] =>
string(4) "Done"
[2] =>
string(5) "Adolf"
}
Odometer
将会在 Abdomen
之前列出,这可能是可取的,也可能不是。 - Roman$diff
检查和return
将消除该行为。 - Matthew$diff = ($b_pos === 0) - ($a_pos === 0);
就足够了。 - Matthewdo
开头 -- 假的评估在真的评估之前$array = [
'Adolf',
'Doe',
'adept',
'Done',
'dear',
'adopt',
'Deer'
];
$startsWith = 'do';
usort(
$array,
fn($a, $b) =>
(stripos($a, $startsWith) !== 0) <=> (stripos($b, $startsWith) !== 0)
?: strcasecmp($a, $b)
);
var_export($array);
array_multisort()
。最终参数($array
)是最终被该函数修改的变量。array_multisort(
array_map(fn($v) => stripos($v, $startsWith) !== 0, $array),
$array,
SORT_STRING | SORT_FLAG_CASE,
$array
);
您可以根据 stripos($str, $search)
对字符串进行排序,这样前面的字符串(stripos() == 0
)将首先出现。
以下代码将搜索字符串的子字符串位置推入单独的数组中,然后使用 array_multisort()
对匹配项应用正确的排序;以这种方式而不是使用 usort()
可避免多次调用 stripos()
。
$k = array_map(function($v) use ($search) {
return stripos($v, $search);
}, $matches);
// $k contains all the substring positions of the search string for all matches
array_multisort($k, SORT_NUMERIC, $matches, SORT_STRING);
// $matches is now sorted against the position
SELECT ... WHERE name LIKE '%$string%'
пјҢеҰӮжһңжҳҜиҝҷж ·пјҢдҪ зҡ„зӯ”жЎҲе°ұи¶іеӨҹдәҶгҖӮжҲ‘еҸӘжҳҜдёәдәҶе®Ңж•ҙжҖ§иҖҢжҢҮеҮәе®ғгҖӮ - Matthew