(PHP)如何使用与变量相关的字符串对多维数组进行排序


(PHP) How to order a multi dimensonal array with strings related to a variable?

嘿,我的网站上有一个新功能,你可以通过在搜索输入中输入一些关键字来搜索ya项目。当然,我使用的是ajax,我需要一个新的函数来对数组进行排序或排序,该数组包含与用户在输入字段中写入的关键字相关的数据库中的项目信息。当用户点击例如"m"时,它应该以这种方式显示。

array [["836","123","Malaga - Ocean","1"],
       ["834","123","Malaga City","1"],
       ["838","123","DayZ - Novo Turm #1","0"],
       ["839","123","DayZ - Novo Turm #2","0"],
       ["840","123","DayZ - Novo Turm #3","0"]]

但是,如果我正在搜索以字母"m"开头的内容,则结果中应首先显示"马拉加市"answers"马拉加-海洋"。

我在多个表中搜索我收集的关键字。但如果我在每个不同的表结果中添加数组,每次图片表都会首先得到结果。

MySql:

$sql_picture = "SELECT * FROM pictures [...] ORDER BY name LIMIT 5";
$sql_videos = "SELECT * FROM videos [...] ORDER BY name LIMIT 5";
$sql_audio = "SELECT * FROM audio [...] ORDER BY name LIMIT 5";
$sql_documents = "SELECT * FROM documents [...] ORDER BY name LIMIT 5";

PHP:

$collectedDataName = array();
for($i = 0; $i < count($collectData); $i++){
    $collectedDataName[$i] = $collectData[$i][2];
}
$collectData_lowercase = array_map('strtolower', $collectedDataName);
array_multisort($collectData_lowercase, SORT_ASC, SORT_STRING, $collectedDataName);
$returnData = array();
for($j = 0; $j < 5; $j++){
    for($i = 0; $i < count($collectData); $i++){
        if($collectData[$i][2] === $collectedDataName[$j]){
            $returnData[$j] = $collectData[$i];
        }
    }
}
echo json_encode($returnData);

结果:

array [["838","123","DayZ - Novo Turm #1","0"],
      ["839","123","DayZ - Novo Turm #2","0"],
      ["840","123","DayZ - Novo Turm #3","0"],
      ["836","123","Malaga - Ocean","1"],
      ["834","123","Malaga City","1"]]

如何根据与变量相关的字符串值对多维数组进行排序

您想要根据输入值对多维数组进行排序,这有点像我们在使用的sql中所做的那样

select * from table where column like 'inputValue%'

这是一个仅基于php的的解决方案

$inputvalue = 'm';
$inputvalue = strtolower($inputvalue);
$collectData = [["838","123","DayZ - Novo Turm #1","0"],
             ["834","123","Malaga City","1"],
             ["839","123","DayZ - Novo Turm #2","0"],         
             ["836","123","Malaga - Ocean","1"],
             ["840","123","DayZ - Novo Turm #3","0"],
            ];
/*
we use strpos to check if the input value is contained in the strings array, if not we use levenshtein to calculate the distance between them.*/
$distances = array();
$positions = array();
for ($i=0; $i < count($collectData); $i++) {    
  $current_val = strtolower($collectData[$i][2]);
  if (strpos($current_val, $inputvalue)!==false)
    $distance = strpos($current_val, $inputvalue);
  else
    $distance = levenshtein($inputvalue, $current_val);
  $distances[] = $distance;        
  $positions[] = array("distance"=>$distance, "position"=>$i);        
}
/*we sort distances*/
sort($distances);
/* we reorder collectData based on distances sort  */
$returnData = array();
for ($j=0; $j<count($distances); $j++) {
  for ($k=0; $k<count($positions); $k++) {
    $val = $collectData[$positions[$k]["position"]];
    if ($distances[$j]==$positions[$k]["distance"] && !in_array($val, $returnData)) {
        $returnData[] = $val;
        break;
    }
  }
}
return $returnData;

levenstein-php-doc在这里:levenstein函数

array_multisort能帮上忙吗?你是要返回只以"m"开头的结果吗?

<?php
// create an array of the "column" to sort on...
foreach ($returnData as $row)  
{
    $test[] = $row[2];
}
// sort it...
array_multisort($test, SORT_DESC, $returnData);
?>

您的问题有两种潜在的解决方案:

1.SQL解决方案

让数据库使用并集为您进行排序。例如:

SELECT
   id1, 
   id2,
   name
FROM
   (
       (SELECT id1, id2, name FROM pictures WHERE something=... ORDER BY name LIMIT 5)
       UNION ALL
       (SELECT id1, id2, name FROM videos WHERE something=... ORDER BY name LIMIT 5)
    ) AS q
ORDER BY
   name

2.PHP解决方案

您正在进行非标准排序,因此需要使用usort,它采用比较两个数组项的比较器函数:

$allData = array_merge($sql_picture, $sql_video, ...);
usort($allData, function($a, $b) { return strcmp($a[2], $b[2]); });