英文:
Laravel Custom Alphabetical Sort callback function
问题
I have a collection of items (shirts) that could be a various range of sizes. The order of the sizes should be as follows.
XS1, XS3, ... S1, S3, ... M1, M3, ... L1, L3, ... XL1, XL3, ... 2XL1, ... 3XL1, ...
Right now when I run the sort,
$items->sortBy('size')
It outputs the results as
2XL#, 3XL#, L#, M#, S# XL#, XS#
which makes sense because that is the natural sort based on alphabetical and numerical orders.
What would be the best way to write a callback function to sort by my specific order needed?
英文:
I have a collection of items (shirts) that could be a various range of sizes. The order of the sizes should be as follows.
XS1, XS3, ... S1, S3, ... M1, M3, ... L1, L3, ... XL1, XL3, ... 2XL1, ... 3XL1, ...
Right now when I run the sort,
$items->sortBy('size')
It outputs the results as
2XL#, 3XL#, L#, M#, S# XL#, XS#
which makes sense because that is the natural sort based on alphabetical and numerical orders.
What would be the best way to write a callback function to sort by my specific order needed?
答案1
得分: 3
以下是您要翻译的内容:
"Shy of modifying your schema so that you can perform the sorting server-side, the various sort methods of the Illuminate Collection class take an optional callable as an argument so that you can provide your own sorting mechanism. Using this, you could define an array of the various sizes you have, in the order that you want them to appear, and then use the position of the target string in that array as your sort comparator:
这段文字描述了使用 Illuminate Collection 类的各种排序方法时,可以提供可选的可调用函数作为参数,以便提供自定义的排序机制。您可以使用这种方式定义一个包含各种尺寸的数组,按照您希望它们出现的顺序排列,并使用目标字符串在该数组中的位置作为排序比较器:"
$collection = collect([
['id' => 1, 'size' => 'S3'],
['id' => 2, 'size' => 'M1'],
['id' => 3, 'size' => 'XS1'],
['id' => 4, 'size' => '3XL1'],
['id' => 5, 'size' => 'S1'],
]);
$sorted = $collection->sortBy([
function($a, $b) {
$order = ['XS1', 'XS3', 'S1', 'S3', 'M1', 'L1', 'L3', 'XL1', 'XL3', '2XL1', '3XL1'];
return array_search($a['size'], $order) <=> array_search($b['size'], $order);
}
]);
print_r($sorted->toArray());
这段代码示例展示了如何使用 Illuminate Collection 类进行排序,并提供了一个自定义排序机制的示例。排序结果如下:
Array
(
[0] => Array
(
[id] => 3
[size] => XS1
)
[1] => Array
(
[id] => 5
[size] => S1
)
[2] => Array
(
[id] => 1
[size] => S3
)
[3] => Array
(
[id] => 2
[size] => M1
)
[4] => Array
(
[id] => 4
[size] => 3XL1
)
)
或者(稍微更高效的方法)您可以将排序数组设为关联数组,其中键是尺寸,值是排序顺序:
$sorted = $collection->sortBy([
function($a, $b) {
$order = [
'XS1' => 0,
'S1' => 1,
'S3' => 2,
'M1' => 3,
'3XL1' => 4,
];
return $order[$a['size']] <=> $order[$b['size']];
}
]);
英文:
Shy of modifying your schema so that you can perform the sorting server-side, the various sort methods of the Illuminate Collection class take an optional callable as an argument so that you can provide your own sorting mechanism. Using this, you could define an array of the various sizes you have, in the order that you want them to appear, and then use the position of the target string in that array as your sort comparator:
$collection = collect([
['id' => 1, 'size' => 'S3'],
['id' => 2, 'size' => 'M1'],
['id' => 3, 'size' => 'XS1'],
['id' => 4, 'size' => '3XL1'],
['id' => 5, 'size' => 'S1'],
]);
$sorted = $collection->sortBy([
function($a, $b) {
$order = ['XS1', 'XS3', 'S1', 'S3', 'M1', 'L1', 'L3', 'XL1', 'XL3', '2XL1', '3XL1'];
return array_search($a['size'], $order) <=> array_search($b['size'], $order);
}
]);
print_r($sorted->toArray());
This yields:
Array
(
[0] => Array
(
[id] => 3
[size] => XS1
)
[1] => Array
(
[id] => 5
[size] => S1
)
[2] => Array
(
[id] => 1
[size] => S3
)
[3] => Array
(
[id] => 2
[size] => M1
)
[4] => Array
(
[id] => 4
[size] => 3XL1
)
)
Alternatively (and slightly more performant) you could make your sort array associative with the key as the size and the value as the sort order:
$sorted = $collection->sortBy([
function($a, $b) {
$order = [
'XS1' => 0,
'S1' => 1,
'S3' => 2,
'M1' => 3,
'3XL1' => 4,
];
return $order[$a['size']] <=> $order[$b['size']];
}
]);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论