通过组合来自多个数组的顺序对数组进行排序
Sort Array by combining orders from multiple Arrays
我正在制作一个简单的搜索引擎,我已经在 MySQL 数据库中索引了很多网站。现在我想通过关键字获得相关的结果列表。
网站在我的数据库中使用以下列进行索引:主机名(没有协议和端口)、标题、描述。 (我们不关心路径)
当我在搜索引擎主页上键入一些关键字时,它首先使用全文索引获取 50 个网站。
现在,因为在 MySQL 中使用 Levenshtein 算法真的很慢,我想用 Levenshtein PHP 函数对我之前列出的每一列的结果进行排序。
我想按以下顺序对它们进行排序(首先是最重要的):主机名、标题,然后是描述。
所以我有五个数组:
- $ 个结果,由 MySQL
返回
- $sorted_by_mysql,包含 $results 的原始顺序的键:0, 1, 2, ...
- $sorted_by_hostname,包含使用 Levenshtein 按主机名相关性排序的 $results 键,例如:3、0、1、2,...
- $sorted_by_title,包含使用 Levenshtein 按标题相关性排序的 $results 键,例如:0、2、1、3,...
- $sorted_by_description,包含使用 Levenshtein 按描述的相关性排序的 $results 键,例如:1、3、0、2、...
代码如下:
$results = $req->fetchAll();
$search = strtolower($q);
$temp_arr = [];
$sorted_by_mysql = $sorted_by_hostname = $sorted_by_title = $sorted_by_description = [];
// We keep the original order in an array
for($i = 0; $i < count($results); $i++) $sorted_by_mysql[] = $i;
// Sort by hostname
for($i = 0; $i < count($results); $i++) $temp_arr[$i] = levenshtein($search, strtolower($results[$i]->hostname));
asort($temp_arr);
foreach($temp_arr as $k => $v) $sorted_by_hostname[] = $k;
// Sort by title
for($i = 0; $i < count($results); $i++) $temp_arr[$i] = levenshtein($search, strtolower($results[$i]->title));
asort($temp_arr);
foreach($temp_arr as $k => $v) $sorted_by_title[] = $k;
// Sort by description
for($i = 0; $i < count($results); $i++) $temp_arr[$i] = levenshtein($search, strtolower($results[$i]->description));
asort($temp_arr);
foreach($temp_arr as $k => $v) $sorted_by_description[] = $k;
最后,我想通过组合(按优先级)所有这些不同的数组来对 $results 进行排序。但我不知道如何做,所以我需要一些帮助!
编辑:解决方案!
$data = $req->fetchAll();
$search = strtolower($q);
$temp = [];
foreach($data as $i => $row) {
$temp[] = [
'id' => $i,
'lev1' => levenshtein($search, strtolower($row->hostname)),
'lev2' => levenshtein($search, strtolower($row->title)),
'lev3' => levenshtein($search, strtolower($row->description))
];
}
$sorted = array_orderby($temp, 'lev1', SORT_ASC, 'lev2', SORT_ASC, 'lev3', SORT_ASC, 'id', SORT_ASC);
$results = [];
foreach($sorted as $row) {
$results[] = $data[$row['id']];
}
// Perfectly sorted !
这里是 array_orderby 函数:
// Credits : jimpoz at jimpoz dot com (PHP.net)
function array_orderby()
{
$args = func_get_args();
$data = array_shift($args);
foreach ($args as $n => $field) {
if (is_string($field)) {
$tmp = array();
foreach ($data as $key => $row)
$tmp[$key] = $row[$field];
$args[$n] = $tmp;
}
}
$args[] = &$data;
call_user_func_array('array_multisort', $args);
return array_pop($args);
}
查看 this SO question, they have a similar need but have structured their data in a way that makes the answer easier. It looks like PHP supports sorting by multiple attributes 的答案(按优先级降序排列),只要这些属性内置到正在排序的关联数组中即可。
要将这种方法应用于您的数据,您可能需要将结果重组为一个巨大的关联数组,其中数组的每个元素都包含一个值,对应于您要排序的每个 "field" .这有意义吗?
祝你好运!
我正在制作一个简单的搜索引擎,我已经在 MySQL 数据库中索引了很多网站。现在我想通过关键字获得相关的结果列表。
网站在我的数据库中使用以下列进行索引:主机名(没有协议和端口)、标题、描述。 (我们不关心路径)
当我在搜索引擎主页上键入一些关键字时,它首先使用全文索引获取 50 个网站。
现在,因为在 MySQL 中使用 Levenshtein 算法真的很慢,我想用 Levenshtein PHP 函数对我之前列出的每一列的结果进行排序。
我想按以下顺序对它们进行排序(首先是最重要的):主机名、标题,然后是描述。
所以我有五个数组:
- $ 个结果,由 MySQL 返回
- $sorted_by_mysql,包含 $results 的原始顺序的键:0, 1, 2, ...
- $sorted_by_hostname,包含使用 Levenshtein 按主机名相关性排序的 $results 键,例如:3、0、1、2,...
- $sorted_by_title,包含使用 Levenshtein 按标题相关性排序的 $results 键,例如:0、2、1、3,...
- $sorted_by_description,包含使用 Levenshtein 按描述的相关性排序的 $results 键,例如:1、3、0、2、...
代码如下:
$results = $req->fetchAll();
$search = strtolower($q);
$temp_arr = [];
$sorted_by_mysql = $sorted_by_hostname = $sorted_by_title = $sorted_by_description = [];
// We keep the original order in an array
for($i = 0; $i < count($results); $i++) $sorted_by_mysql[] = $i;
// Sort by hostname
for($i = 0; $i < count($results); $i++) $temp_arr[$i] = levenshtein($search, strtolower($results[$i]->hostname));
asort($temp_arr);
foreach($temp_arr as $k => $v) $sorted_by_hostname[] = $k;
// Sort by title
for($i = 0; $i < count($results); $i++) $temp_arr[$i] = levenshtein($search, strtolower($results[$i]->title));
asort($temp_arr);
foreach($temp_arr as $k => $v) $sorted_by_title[] = $k;
// Sort by description
for($i = 0; $i < count($results); $i++) $temp_arr[$i] = levenshtein($search, strtolower($results[$i]->description));
asort($temp_arr);
foreach($temp_arr as $k => $v) $sorted_by_description[] = $k;
最后,我想通过组合(按优先级)所有这些不同的数组来对 $results 进行排序。但我不知道如何做,所以我需要一些帮助!
编辑:解决方案!
$data = $req->fetchAll();
$search = strtolower($q);
$temp = [];
foreach($data as $i => $row) {
$temp[] = [
'id' => $i,
'lev1' => levenshtein($search, strtolower($row->hostname)),
'lev2' => levenshtein($search, strtolower($row->title)),
'lev3' => levenshtein($search, strtolower($row->description))
];
}
$sorted = array_orderby($temp, 'lev1', SORT_ASC, 'lev2', SORT_ASC, 'lev3', SORT_ASC, 'id', SORT_ASC);
$results = [];
foreach($sorted as $row) {
$results[] = $data[$row['id']];
}
// Perfectly sorted !
这里是 array_orderby 函数:
// Credits : jimpoz at jimpoz dot com (PHP.net)
function array_orderby()
{
$args = func_get_args();
$data = array_shift($args);
foreach ($args as $n => $field) {
if (is_string($field)) {
$tmp = array();
foreach ($data as $key => $row)
$tmp[$key] = $row[$field];
$args[$n] = $tmp;
}
}
$args[] = &$data;
call_user_func_array('array_multisort', $args);
return array_pop($args);
}
查看 this SO question, they have a similar need but have structured their data in a way that makes the answer easier. It looks like PHP supports sorting by multiple attributes 的答案(按优先级降序排列),只要这些属性内置到正在排序的关联数组中即可。
要将这种方法应用于您的数据,您可能需要将结果重组为一个巨大的关联数组,其中数组的每个元素都包含一个值,对应于您要排序的每个 "field" .这有意义吗?
祝你好运!