如何按特定列值的前导整数对子数组进行排序?
Posted
技术标签:
【中文标题】如何按特定列值的前导整数对子数组进行排序?【英文标题】:How to sort a subarrays by the leading integers of a specific column value? 【发布时间】:2011-08-20 01:55:57 【问题描述】:下面的数组应该按照cat_url_title
的第一个数字升序排序。
Array
(
[0] => Array
(
[cat_id] => 14
[parent_id] => 2
[cat_url_title] => 20-a-43m
)
[1] => Array
(
[cat_id] => 13
[parent_id] => 2
[cat_url_title] => 16-a-20m
)
[2] => Array
(
[cat_id] => 12
[parent_id] => 2
cat_url_title] => 12-a-16m
)
)
//get the first number
foreach( $arr as $k => $v )
$segs = explode("-",$v['cat_url_title']);
$nbr = $segs[0]; //this will be 20, 16 or 12
cat_url_title
值以12
开头的子数组应变为$arr[0]
,16
应保持为$arr[1]
,20
应移动到$arr[2]
。
我怎样才能做到这一点?
【问题讨论】:
php.net/manual/en/function.array-walk.php 那个“a”是什么?意思是“我”还是什么? “a”是法语“to”的意思,这会打印出产品标签,例如尺寸为 12 到 16 米的产品。 【参考方案1】:你的方法很好,在获得第一个数字后,创建一个新数组,其中包含数字作为键,数组的内容作为值:
$newArray = array();
foreach($arr as $k => $v)
$segs = explode("-", $v['cat_url_title']);
$newArray[ $segs[0] ] = $v;
ksort($newArray);
print_r($newArray);
应该可以的。
【讨论】:
对不起! *** 的新手,这不是完全允许的还是只是不提供完整解决方案的指南? 我自己的指南 :) 如果您将鼠标悬停在有问题的“作业”标签上,您会看到一些关于它的描述。它指出,允许询问有关家庭作业的问题,“只要他们被诚实地询问,解释问题并表现出足够的努力”。这让我觉得也应该给出答案,以便作者必须表现出一些努力。 有效!只是想知道,是什么决定了一个问题是否是家庭作业?我十年前毕业了:) P.S.其他类型的问题有时需要完整的解决方案,有时他们只需要一些指导(伪代码或其他东西) - 取决于问题的类型。这只是一个特例 - 家庭作业,因此恕我直言,我们应该让他思考,并且只是帮助解决问题(而不是代替他解决问题)。这是我们能做的最好的事情来帮助他有一天成为一名伟大的程序员:) @stef,好吧......问题是标记为“家庭作业”。那么我们应该问 KingCrunch,他为什么要添加那个标签 :) 无论如何,虽然这可行,但我建议查看usort()
函数,并查看 p4bl0 提供的链接。 PHP 拥有大量用于处理数组的函数。【参考方案2】:
usort()
【讨论】:
链接支持一个好的答案,但不构成一个单独的好答案。请对您的知识更加慷慨,并编辑此帖子不仅仅是重定向。 @mickmackusa,虽然我同意写一个更完整的答案会更好,但我想指出,这个答案已有 8.5 年历史,而且知识早已丢失. 带有 UV 的仅链接的旧答案邀请新志愿者模仿行为。不适合这个网站。【参考方案3】:参见usort() php 函数。
关于 php 中数组排序函数的有趣页面:http://us.php.net/manual/en/array.sorting.php
【讨论】:
链接支持一个好的答案,但不构成一个单独的好答案。请对您的知识更加慷慨,并编辑此帖子不仅仅是重定向。【参考方案4】:单线:
array_multisort(array_map('end', $array), SORT_NUMERIC, $array);
假设:
$array = array (
0 => array (
'cat_id' => 14,
'parent_id' => 2,
'cat_url_title' => '20-a-43m'
),
1 => array (
'cat_id' => 13,
'parent_id' => 2,
'cat_url_title' => '16-a-20m'
),
2 => array (
'cat_id' => 12,
'parent_id' => 2,
'cat_url_title' => '12-a-16m'
)
);
【讨论】:
【参考方案5】:这是我用来对数组进行排序的函数:
function array_sort($array, $on, $order='SORT_DESC' /*or SORT_ASC*/ )
$new_array = array();
$sortable_array = array();
if (count($array) > 0)
foreach ($array as $k => $v)
if (is_array($v))
foreach ($v as $k2 => $v2)
if ($k2 == $on)
$sortable_array[$k] = $v2;
else
$sortable_array[$k] = $v;
switch($order)
case 'SORT_ASC':
asort($sortable_array);
break;
case 'SORT_DESC':
arsort($sortable_array);
break;
foreach($sortable_array as $k => $v)
$new_array[] = $array[$k];
return $new_array;
用法:
array_sort($restaurants_top, "score", 'SORT_DESC');
$restaurants_top = 餐厅列表 "score" = 数组键 SORT_DESC = 排序方向
【讨论】:
【参考方案6】:Tomasz 对array_multisort() 的建议是一种聪明的、声明性的、简洁的技术,多年来一直在php 版本中可用。如果此任务在我的项目中,我可能会使用 array_multisort()
。
我可能会建议,为了项目稳定性(以防数据结构被扩展/更改),明确命名要排序的列。下面的 sn-p 也避免了重复的 end()
调用。
array_multisort(array_column($array, 'cat_url_title'), SORT_NUMERIC, $array);
我将展示几个现代替代方案作为学术练习。
从 PHP7 开始,spaceship operator 也提供了简洁的语法。在第一个连字符之前隔离数字子字符串,将字符串转换为整数。
usort($array, function($a, $b)
return (int)$a['cat_url_title'] <=> (int)$b['cat_url_title'];
);
从 PHP7.4 开始,arrow function syntax 使 usort()
调用更加简洁,但如果您不习惯这种语法,读起来可能会更加神秘。
usort($array, fn($a, $b) => (int)$a['cat_url_title'] <=> (int)$b['cat_url_title']);
与我几乎所有的 php 帖子一样,这里是 an online demo 以证明我的所有 sn-ps 功能都符合预期。
应避免在此页面上多次迭代输入数组的片段。
附言如果您希望对四个数字/字母子字符串的cat_url_title
值进行排序,您可以将这些子字符串写为 spaceship 运算符两侧的数组,它将从左到右评估子字符串以确定排序结果。
代码:(Demo)
usort($array, function($a, $b)
return (preg_match_all('~[a-z]+|\d+~', $a['cat_url_title'], $out) ? $out[0] : ['','','',''])
<=>
(preg_match_all('~[a-z]+|\d+~', $b['cat_url_title'], $out) ? $out[0] : ['','','','']);
);
p.p.s.这对于version_compare()
来说可能是一个很好的例子。不幸的是,我的测试电池中的字符串不可靠。记下16-a-20n
子数组在此demo 中的最终位置。我相信该函数忽略了最后一个字母,因为评估是在16-a-20m
和16-a-20n
之间的0
。
对于具有一致的a
和m
子字符串位置的示例字符串,它可以完美地自然排序。
代码:(Demo)
usort($array, function($a, $b)
return version_compare($a['cat_url_title'], $b['cat_url_title']);
);
【讨论】:
以上是关于如何按特定列值的前导整数对子数组进行排序?的主要内容,如果未能解决你的问题,请参考以下文章