提问人:Gabriel91 提问时间:10/25/2023 最后编辑:mickmackusaGabriel91 更新时间:10/25/2023 访问量:38
按前半部分升序和后半部分降序对分隔数组值进行排序
Sort delimited array values by first half ascending then by second half descending
问:
我正在尝试使用大小对数组值进行排序,但结果与我预期不符。 这是我的代码:
function cmp($a, $b) {
$sizes = array(
"XS" => 0,
"S" => 1,
"M" => 2,
"L" => 3,
);
$size_a = explode("_", $a)[1];
$size_b = explode("_", $b)[1];
return $sizes[$size_a] <=> $sizes[$size_b];
}
$array = array("GL001_M","GL001_XS","GL001_S",
"GL001_L","GL002_M","GL002_XS",
"GL002_S","GL002_L");
usort($array,"cmp");
foreach($array as $arrayItem){
echo $arrayItem.' | ';
}
我的输出是这样的:
GL001_XS | GL002_XS | GL001_S | GL002_S | GL001_M | GL002_M | GL001_L | GL002_L |
相反,我想要这个:
GL001_XS | GL001_S | GL001_M | GL001_L | GL002_XS | GL002_S | GL002_M | GL002_L |
答:
3赞
Nigel Ren
10/25/2023
#1
当前方法的问题在于它只对每个字符串的最后部分(如“S”、“XS”等)进行排序。
您可以做的是扩展比较以对第一部分(“GL001”)进行排序,并且仅在存在匹配项时才使用大小对它们进行排序。
$size_a = explode('_', $a);
$size_b = explode('_', $b);
return ($size_a[0] <=> $size_b[0]) ?: $sizes[$size_a[1]] <=> $sizes[$size_b[1]];
因此将比较“GL001”位。$size_a[0] <=> $size_b[0]
如果第一部分的值为 0(即它们相同),则使用它将返回第二部分。
将是数组转换的大小(所以 'S' => 1)。?:
$sizes[$size_a[1]]
0赞
mickmackusa
10/25/2023
#2
哇,这个问题与表示大小(XXS、XS、S、M、L、XL、XXL)的值后缀的自定义排序非常相似,但事实上,您按输入字符串的两半进行排序,并且所需的大小值可以按字母顺序排序,我的建议会改变。不需要查找数组。使用线性时间复杂度的调用意味着每次迭代的调用次数少于 2 次。explode()
explode()
usort()
代码:(演示)
$ids = [];
$sizes = [];
foreach ($array as $v) {
[$ids[], $sizes[]] = explode('_', $v, 2);
}
array_multisort($ids, $sizes, SORT_DESC, $array);
var_export($array);
一旦必须容纳大于 的大小,就需要一个查找数组。L
代码:(演示)
define('SIZES', array_flip(['XXS', 'XS', 'S', 'M', 'L', 'XL', 'XXL']));
$ids = [];
$sizes = [];
foreach ($array as $v) {
[$ids[], $size] = explode('_', $v, 2);
$sizes[] = SIZES[$size];
}
array_multisort($ids, $sizes, $array);
var_export($array);
如果你对与你合作的其他开发人员非常不满,你就会用这个功能齐全的风格片段让他们眼花缭乱,没有新的、全局范围的变量!演示
define('SIZES', array_flip(['XXS', 'XS', 'S', 'M', 'L', 'XL', 'XXL']));
array_multisort(
...array_merge(
array_map(
null,
...array_map(
fn($v) =>
(fn($id, $size) => [$id, SIZES[$size]])(...explode('_', $v, 2)),
$array
)
),
[&$array]
)
);
var_export($array);
评论