通过组合多个阵列的订单对阵列进行排序

时间:2015-04-30 14:10:58

标签: php sorting levenshtein-distance

我正在制作一个简单的搜索引擎,而且我已经在MySQL数据库中索引了很多网站。现在,我希望通过关键字获得相关的结果列表。

网站在我的数据库中使用以下列编制索引:主机名(没有协议和端口),标题,说明。 (我们不关心路径)

当我在搜索引擎主页上输入一些关键字时,首先是使用FULLTEXT索引获取50个网站。

现在,因为在MySQL中使用Levenshtein算法非常慢,我想用Levenshtein PHP函数对我之前列出的每个列进行排序。

我想按此顺序排序(最重要的是第一个):主机名,标题,然后说明。

所以我有五个数组:

  • $结果,由MySQL返回
  • $ sorted_by_mysql,包含原始订单中$ result的键: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排序,例如: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;

最后,我想通过组合(优先级)所有thoses不同的数组来排序$ 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);
}

1 个答案:

答案 0 :(得分:1)

查看this SO question的答案,他们有类似的需求,但已经以一种使答案更容易的方式构建他们的数据。看起来PHP支持sorting by multiple attributes(降序优先级),只要这些属性被构建到正在排序的关联数组中。

要将此方法应用于您的数据,您可能希望将结果重组为一个巨型关联数组,其中数组的每个元素都包含您要分类的每个“字段”的值。这有意义吗?

祝你好运!