简体   繁体   中英

How can I combine this Laravel Collection sort?

This is what I currently have:

    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();

Basically I'd like to sort by $order first and then tweak the order based on $landOrder.

Currently it sorts by whichever function was executed second. How can I make it so it sorts for both?

I would use the sort method instead of sortBy . The sort method uses the PHP uasort function, which gives you a little more control over the sorting functionality.

$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();

Edit

You'll need to update the function to implement whatever logic is needed to get the correct index from the $order and $landOrder arrays. I just used array_search() as a quick and easy function, but this assumes that the value of the types and supertypes attributes would be exact matches to the entries in the arrays (ie 'Land' and 'Basic', not '["Land"]' and '["Basic"]').

Based on the logic from your question, and the format of the attributes from your comments, you're probably looking for something like this:

$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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM