我怎样才能组合这个 Laravel 集合排序?
How can I combine this Laravel Collection sort?
这是我目前拥有的:
use Illuminate\Support\Collection;
$order = ['Land', 'Planeswalker', 'Creature', 'Instant', 'Sorcery', 'Enchantment', 'Artifact'];
$landOrder = ['Basic', ''];
$deck = $deck->sortBy(function($card) use ($landOrder) {
foreach ($landOrder as $index => $supertypes) {
if (str_contains($card->supertypes, $supertypes)) {
return $index;
}
}
})->values();
$deck = $deck->sortBy(function($card) use ($order) {
foreach ($order as $index => $type) {
if (str_contains($card->types, $type)) {
return $index;
}
}
})->values();
基本上我想先按 $order 排序,然后根据 $landOrder 调整顺序。
目前它按第二个执行的函数排序。我怎样才能让它对两者都排序?
我会使用 sort
方法而不是 sortBy
。 sort
方法使用 PHP uasort
函数,它使您可以更好地控制排序功能。
$deck->sort(function($a, $b) use ($order, $landOrder) {
// get the order indexes for the two items
$ai = array_search($a->types, $order);
$bi = array_search($b->types, $order);
// if the two items have the same order, drill down to the land order comparison
if ($ai === $bi) {
// get the land order indexes for the two items
$aii = array_search($a->supertypes, $landOrder);
$bii = array_search($b->supertypes, $landOrder);
// order based on "natural order" comparison of land order indexes
return strnatcmp($aii, $bii);
}
// order based on "natural order" comparison of order indexes
return strnatcmp($ai, $bi);
})->values();
编辑
您需要更新函数以实现从 $order
和 $landOrder
数组中获取正确索引所需的任何逻辑。我只是使用 array_search()
作为一个快速简单的函数,但这假设 types
和 supertypes
属性的值将与数组中的条目完全匹配(即 'Land' 和 'Basic',而不是“["Land"]”和“["Basic"]”)。
根据您问题的逻辑以及您评论中的属性格式,您可能正在寻找这样的东西:
$deck->sort(function($a, $b) use ($order, $landOrder) {
// get the order indexes for the two items
$ai = null;
$bi = null;
foreach ($order as $index => $type) {
if (str_contains($a->types, $type)) {
$ai = $index;
}
if (str_contains($b->types, $type)) {
$bi = $index;
}
}
// if the type is not in the array, assign some type of value that will order like types together, but after all other proper types
if (is_null($ai)) {
$ai = count($order).$a->types;
}
if (is_null($bi)) {
$bi = count($order).$b->types;
}
// if the two items have the same order, drill down to the land order comparison
if ($ai === $bi) {
// get the land order indexes for the two items
$aii = null;
$bii = null;
foreach ($landOrder as $index => $supertype) {
if (str_contains($a->supertypes, $supertype)) {
$aii = $index;
}
if (str_contains($b->supertypes, $supertype)) {
$bii = $index;
}
}
// if the supertype is not in the array, assign some type of value that will order like supertypes together, but after all other proper supertypes
if (is_null($aii)) {
$aii = count($landOrder).$a->supertypes;
}
if (is_null($bii)) {
$bii = count($landOrder).$b->supertypes;
}
// order based on "natural order" comparison of land order indexes
return strnatcmp($aii, $bii);
}
// order based on "natural order" comparison of order indexes
return strnatcmp($ai, $bi);
})->values();
这是我目前拥有的:
use Illuminate\Support\Collection;
$order = ['Land', 'Planeswalker', 'Creature', 'Instant', 'Sorcery', 'Enchantment', 'Artifact'];
$landOrder = ['Basic', ''];
$deck = $deck->sortBy(function($card) use ($landOrder) {
foreach ($landOrder as $index => $supertypes) {
if (str_contains($card->supertypes, $supertypes)) {
return $index;
}
}
})->values();
$deck = $deck->sortBy(function($card) use ($order) {
foreach ($order as $index => $type) {
if (str_contains($card->types, $type)) {
return $index;
}
}
})->values();
基本上我想先按 $order 排序,然后根据 $landOrder 调整顺序。
目前它按第二个执行的函数排序。我怎样才能让它对两者都排序?
我会使用 sort
方法而不是 sortBy
。 sort
方法使用 PHP uasort
函数,它使您可以更好地控制排序功能。
$deck->sort(function($a, $b) use ($order, $landOrder) {
// get the order indexes for the two items
$ai = array_search($a->types, $order);
$bi = array_search($b->types, $order);
// if the two items have the same order, drill down to the land order comparison
if ($ai === $bi) {
// get the land order indexes for the two items
$aii = array_search($a->supertypes, $landOrder);
$bii = array_search($b->supertypes, $landOrder);
// order based on "natural order" comparison of land order indexes
return strnatcmp($aii, $bii);
}
// order based on "natural order" comparison of order indexes
return strnatcmp($ai, $bi);
})->values();
编辑
您需要更新函数以实现从 $order
和 $landOrder
数组中获取正确索引所需的任何逻辑。我只是使用 array_search()
作为一个快速简单的函数,但这假设 types
和 supertypes
属性的值将与数组中的条目完全匹配(即 'Land' 和 'Basic',而不是“["Land"]”和“["Basic"]”)。
根据您问题的逻辑以及您评论中的属性格式,您可能正在寻找这样的东西:
$deck->sort(function($a, $b) use ($order, $landOrder) {
// get the order indexes for the two items
$ai = null;
$bi = null;
foreach ($order as $index => $type) {
if (str_contains($a->types, $type)) {
$ai = $index;
}
if (str_contains($b->types, $type)) {
$bi = $index;
}
}
// if the type is not in the array, assign some type of value that will order like types together, but after all other proper types
if (is_null($ai)) {
$ai = count($order).$a->types;
}
if (is_null($bi)) {
$bi = count($order).$b->types;
}
// if the two items have the same order, drill down to the land order comparison
if ($ai === $bi) {
// get the land order indexes for the two items
$aii = null;
$bii = null;
foreach ($landOrder as $index => $supertype) {
if (str_contains($a->supertypes, $supertype)) {
$aii = $index;
}
if (str_contains($b->supertypes, $supertype)) {
$bii = $index;
}
}
// if the supertype is not in the array, assign some type of value that will order like supertypes together, but after all other proper supertypes
if (is_null($aii)) {
$aii = count($landOrder).$a->supertypes;
}
if (is_null($bii)) {
$bii = count($landOrder).$b->supertypes;
}
// order based on "natural order" comparison of land order indexes
return strnatcmp($aii, $bii);
}
// order based on "natural order" comparison of order indexes
return strnatcmp($ai, $bi);
})->values();