TL; DR
按键排序/分组数组而不向数组添加其他级别(由jQuery插件解析的数据)?
详细信息
我正在构建一个数组以返回到某些<select>
DOM元素。
它将CC(引擎大小的东西)作为参数并将其用作键,问题出在对数组进行排序之后。
比方说,用户选择此CC范围:
50、100、125
50有32个可用选项
100有3个可用选项
125有12个可用选项
我当前的代码遍历CC,执行SQL以获取选项,并使用循环计数器创建如下密钥:
$options[$cc. $id] = $someValue;
这可以按您期望的方式工作,但是我的输出显示的结果与我所需的顺序不完全相同(CC ASC
-因此所有50年代应该一起显示)。
问题是
50(带32)上升为
5031
作为键。 100(带3)上升为1002
作为键。 125与12连为最高12511
。
现在希望您可以清楚地看到该问题。 5031大于1002。因此,循环计数器传递9的50cc选项大于100cc选项。
(为清楚起见,示例输出为):
50cc选项1
50cc选项2
50cc选项3
50cc选项4
50cc选项5
100cc选项1
100cc选项2
100cc选项3
50cc选件6
50cc选项7
也许最初的问题是我如何创建密钥,但是我尝试将ksort
与几个不同的标志一起使用以尝试实现我的目标,但是这些标志似乎都没有针对我的目标m之后:
SORT_REGULAR - compare items normally (don't change types) SORT_NUMERIC - compare items numerically SORT_STRING - compare items as strings SORT_LOCALE_STRING - compare items as strings, based on the current locale. It uses the locale, which can be changed using setlocale() SORT_NATURAL - compare items as strings using "natural ordering" like natsort() SORT_FLAG_CASE - can be combined (bitwise OR) with SORT_STRING or SORT_NATURAL to sort strings case-insensitively
如何在不将其他级别添加到数组的情况下对键进行排序/分组(数据由需要以某种格式的数据的jQuery插件解析)?
编辑:完整脚本
<?php
if (strpos(PHP_OS, 'Linux') > -1) {
require_once $_SERVER['DOCUMENT_ROOT']. '/app/connect.php';
} else {
require_once getcwd(). '\\..\\..\\..\\..\\app\\connect.php';
}
$make = $_POST['make'];
$cc = $_POST['cc'];
$sql = 'SELECT * FROM `table`
WHERE `UKM_CCM` = :cc
AND `UKM_Make` = :make
ORDER BY `UKM_Model`, `UKM_StreetName`, `Year` ASC;';
$options = array();
foreach ($cc as $k => $value)
{
$res = $handler->prepare($sql);
$res->execute(array(':cc' => $value, ':make' => $make));
$data = $res->fetchAll(PDO::FETCH_ASSOC);
$i = 0;
if (count($data) > 0) {
foreach ($data as $result)
{
$arrayKey = sprintf('%03d%02d', $cc, $i);
$epid = $result['ePID'];
$make = $result['UKM_Make'];
$model = $result['UKM_Model'];
$cc = $result['UKM_CCM'];
$year = $result['Year'];
$sub = $result['UKM_Submodel'];
$street = $result['UKM_StreetName'];
$options[$arrayKey]['name'] = $make. ' ' .$model. ' ' .$cc. ' ' .$year. ' ' .$sub. ' ' .$street;
$options[$arrayKey]['value'] = $epid;
$options[$arrayKey]['checked'] = false;
$options[$arrayKey]['attributes']['data-epid'] = $epid;
$options[$arrayKey]['attributes']['data-make'] = $make;
$options[$arrayKey]['attributes']['data-model'] = $model;
$options[$arrayKey]['attributes']['data-cc'] = $cc;
$options[$arrayKey]['attributes']['data-year'] = $year;
$options[$arrayKey]['attributes']['data-sub'] = $sub;
$options[$arrayKey]['attributes']['data-street'] = $street;
$i++;
}
}
}
ksort($options, SORT_STRING);
echo json_encode($options);
答案 0 :(得分:2)
您可以将密钥的格式设置为cc的3位数字和选项的2位数字...
$options[sprintf('%03d%02d', $cc, $id)] = $someValue;
应该为您提供密钥05031
和10002
。
然后使用SORT_STRING
强制其将它们按字符串排序(尽管它们也将按数字排序)
答案 1 :(得分:0)
如果您可以将其他密钥添加到数组中,则可以创建一个usort()
,该数组将根据需要对数组进行排序:
$arrSort = [50, 100, 125];
$arrData = [
501 => [
'foo',
'bar',
'arrayKey' => 501
],
504 => [
'foo',
'bar',
'arrayKey' => 504
],
1002 => [
'foo',
'bar',
'arrayKey' => 1002
],
10045 => [
'foo',
'bar',
'arrayKey' => 10045
],
1251 => [
'foo',
'bar',
'arrayKey' => 1251
],
5045 => [
'foo',
'bar',
'arrayKey' => 5045
]
];
usort($arrData, function($a, $b) use ($arrSort)
{
$posA = array_search(substr($a['arrayKey'], 0, 2), $arrSort);
if ($posA === false) {
$posA = array_search(substr($a['arrayKey'], 0, 3), $arrSort);
}
$posB = array_search(substr($b['arrayKey'], 0, 2), $arrSort);
if ($posB === false) {
$posB = array_search(substr($b['arrayKey'], 0, 3), $arrSort);
}
return $posA - $posB;
});
此示例中此函数的返回为:
数组:6 [▼0 =>数组:3 [▼ 0 =>“ foo” 1 =>“栏” “ arrayKey” => 501] 1 => array:3 [▼ 0 =>“ foo” 1 =>“栏” “ arrayKey” => 504] 2 => array:3 [▼ 0 =>“ foo” 1 =>“栏” “ arrayKey” => 5045] 3 => array:3 [▼ 0 =>“ foo” 1 =>“栏” “ arrayKey” => 1002] 4 => array:3 [▼ 0 =>“ foo” 1 =>“栏” “ arrayKey” => 10045] 5 => array:3 [▼ 0 =>“ foo” 1 =>“栏” “ arrayKey” => 1251]]
答案 2 :(得分:0)
在此示例中,使“仿形分隔符”成为不常见的模式,例如“ 929292”。然后,您可以使用uksort仅浏览密钥。用“替换”“ 929292”。因此您最终得到的是“ 100.3”,“ 125.12”和“ 150.32”。
现在,您不再局限于尝试进行数字运算和使用模式,您可以使用一个很好的旧爆炸并手动进行比较。
此解决方案不关心数组中嵌套的内容,仅与排序键有关。
$options = [
'1009292923' => '100cc',
'12592929212' => '150cc',
'5092929232' => '50cc'
];
$sorted = uksort($options, function($a, $b){
$parts = explode('.',str_replace('929292', '.', $a));
$acc = $parts[0];
$parts = explode('.',str_replace('929292', '.', $b));
$bcc = $parts[0];
if($acc == $bcc) { return 0; }
if($acc > $bcc) { return 1; }
if($acc < $bcc) { return -1; }
});
var_dump($options);
编辑:这里的str_replace毫无意义,您可以使用“ 929292”作为分隔符直接在键上运行爆炸。
答案 3 :(得分:0)
我不确定这是否可以解决我自己的问题,因为它可以解决问题,但方式不同。本质上,我已将SQL更改为此:
$sql = 'SELECT * FROM `ebay_mml`
WHERE `UKM_CCM` IN ('. $where .')
AND `UKM_Make` = :make
ORDER BY CAST(SUBSTR(`UKM_CCM`, INSTR(`UKM_CCM`, " ") + 1) AS UNSIGNED),
`UKM_Model`,
`UKM_StreetName`,
`Year`
ASC;';
$where
是从foreach循环生成的变量:
foreach ($cc as $k => $v)
{
$where .= ':'. $k .($k != end(array_keys($cc)) ? ', ' : '');
$whereData[':'. $k] = $v;
}
这会立即返回我的所有数据,所以我现在要做的就是遍历结果并在构建键时计算迭代次数:
$i = 0;
foreach ($data as $result)
{
# my sexy code
$i++;
}
现在我的结果如我所愿。
免责声明:因为这确实解决了手头的问题,所以它与最初提出的问题有所偏离,因为它更多是一种MySQL解决方案,而不是按键值对数组进行排序/分组。让我知道这个答案是否可以(如果可以,将删除免责声明部分)。
感谢您的帮助:)