Skip to content

Commit

Permalink
Merge pull request #4 from TheDragonCode/1.x
Browse files Browse the repository at this point in the history
Added the ability to change the sort order of logical groups
  • Loading branch information
andrey-helldar authored Feb 2, 2023
2 parents 3807204 + 7a92269 commit 3f39d59
Show file tree
Hide file tree
Showing 5 changed files with 539 additions and 22 deletions.
46 changes: 45 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,51 @@ $items = Size::query()->get();
return Sorter::sort($items, 'title');
```

> You can see more examples in the [test file](tests/Sorters/StaticallyTest.php).
> You can see more examples in the [test file](tests/Sorters/SorterTest.php).
### Groups Order

By default, sizes are sorted by the following logical blocks:

1. Letter clothing size (XXS, XS, M, L, etc.)
2. Numerical size of clothes and shoes (9, 10, 44-46, 48, etc.)
3. Bra size (70B, 75A, 80C, etc...)
4. Overall dimensions of items (40x38x19 sm, etc.)
5. Other values

But you can change the order by specifying identifiers as the third parameter:

```php
use DragonCode\SizeSorter\Enum\Group;
use DragonCode\SizeSorter\Sorter;

return Sorter::sort($items, groupsOrder: [3, 5, 4, 2, 1]);
// or
return Sorter::sort($items, groupsOrder: [Group::GROUP_3, Group::GROUP_5, Group::GROUP_4, Group::GROUP_2, Group::GROUP_1]);
```

The final array will be formed in the specified order:

```
3 - 5 - 4 - 2 - 1
```

You can also specify some groups. For example:

```php
use DragonCode\SizeSorter\Enum\Group;
use DragonCode\SizeSorter\Sorter;

return Sorter::sort($items, groupsOrder: [3, 5]);
// or
return Sorter::sort($items, groupsOrder: [Group::GROUP_3, Group::GROUP_5]);
```

In this case, the first two logical groups will be sorted in the specified order, and the subsequent ones will be in ascending order:

```
3 - 5 - 1 - 2 - 4
```

## License

Expand Down
68 changes: 68 additions & 0 deletions src/Services/Order.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

namespace DragonCode\SizeSorter\Services;

use DragonCode\SizeSorter\Enum\Group;

class Order
{
public static function resolve(?array $groups): array
{
return ! empty($groups)
? static::fill($groups)
: static::groups();
}

protected static function fill(array $groups): array
{
return static::fillDefault(
static::fillCustom($groups)
);
}

protected static function fillCustom(array $groups): array
{
$result = [];

foreach ($groups as $group) {
$value = static::resolveValue($group);

if (static::existGroup($value)) {
$result[] = $value;
}
}

return $result;
}

protected static function fillDefault(array $groups): array
{
foreach (static::groups() as $group) {
if (! in_array($group, $groups)) {
$groups[] = $group;
}
}

return $groups;
}

protected static function existGroup(int $value): bool
{
return Group::exists($value);
}

/**
* @return array<Group>
*/
protected static function groups(): array
{
return Group::values();
}

protected static function resolveValue(Group|int $group): int
{
return $group->value ?? $group;
}
}
60 changes: 39 additions & 21 deletions src/Sorter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,49 @@
use DragonCode\SizeSorter\Enum\Group;
use DragonCode\SizeSorter\Services\Collection;
use DragonCode\SizeSorter\Services\GroupsDetector;
use DragonCode\SizeSorter\Services\Order;
use DragonCode\SizeSorter\Services\Resolver;
use DragonCode\SizeSorter\Services\Sorter as SorterService;
use DragonCode\Support\Helpers\Ables\Stringable;
use Illuminate\Support\Collection as IlluminateCollection;
use Illuminate\Support\Collection as IC;

class Sorter
{
public static function sort(IlluminateCollection $items, string $column = 'value'): IlluminateCollection
public static function sort(IC $items, string $column = 'value', ?array $groupsOrder = null): IC
{
return static::handle($items, $column);
return static::flatten(
static::handle($items, $column, Order::resolve($groupsOrder))
);
}

protected static function handle(IlluminateCollection $items, string $column = 'value'): IlluminateCollection
protected static function handle(IC $items, string $column, array $groupsOrder): IC
{
return static::flatten(
static::sorting($items, $column)
);
return static::orderGroups(static::sorting($items, $column), $groupsOrder);
}

public static function sorting(IlluminateCollection $items, string $column = 'value'): IlluminateCollection
protected static function orderGroups(IC $items, array $order): IC
{
$result = static::collect();

foreach ($order as $key) {
if ($items->has($key)) {
$result->put($key, $items->get($key));
}
};

return $result;
}

protected static function sorting(IC $items, string $column = 'value'): IC
{
return $items
->groupBy(static fn (mixed $size) => static::detectGroup(
static::resolveValue($size, $column)->toString()
), true)
->sortKeys()
->map(static fn (IlluminateCollection $items, int $group) => static::sortByGroup($items, $group, $column));
->map(static fn (IC $items, int $group) => static::sortByGroup($items, $group, $column));
}

public static function sortByGroup(IlluminateCollection $items, int $group, string $column): IlluminateCollection
protected static function sortByGroup(IC $items, int $group, string $column): IC
{
return match ($group) {
Group::GROUP_1() => static::sortChars($items, $column),
Expand All @@ -45,7 +58,7 @@ public static function sortByGroup(IlluminateCollection $items, int $group, stri
};
}

public static function sortChars(IlluminateCollection $values, string $column): IlluminateCollection
protected static function sortChars(IC $values, string $column): IC
{
return $values->groupBy(
static fn (mixed $size) => static::resolveValue($size, $column)
Expand All @@ -55,53 +68,58 @@ public static function sortChars(IlluminateCollection $values, string $column):
)
->sortKeysDesc()
->map(
static fn (IlluminateCollection $values, string $group) => $group === 's'
static fn (IC $values, string $group) => $group === 's'
? static::sortSmallSizes($values, $column)
: static::sortArrows($values, $column)
);
}

public static function sortSmallSizes(IlluminateCollection $values, string $column): IlluminateCollection
protected static function sortSmallSizes(IC $values, string $column): IC
{
return $values->sort(
SorterService::byArrow($column, -1)
)
->groupBy(static fn (mixed $size) => static::resolveValue($size, $column)->toString(), true)
->map(static fn (IlluminateCollection $values) => static::sortSpecialChars($values, $column));
->map(static fn (IC $values) => static::sortSpecialChars($values, $column));
}

public static function sortSpecialChars(IlluminateCollection $values, string $column): IlluminateCollection
protected static function sortSpecialChars(IC $values, string $column): IC
{
return $values->sort(
SorterService::byChars($column)
);
}

public static function sortArrows(IlluminateCollection $values, string $column): IlluminateCollection
protected static function sortArrows(IC $values, string $column): IC
{
return $values->sort(
SorterService::byArrow($column)
);
}

public static function sortNumbers(IlluminateCollection $items, string $column): IlluminateCollection
protected static function sortNumbers(IC $items, string $column): IC
{
return $items->sort(
SorterService::byNumbers($column)
);
}

public static function detectGroup(string $value): int
protected static function detectGroup(string $value): int
{
return GroupsDetector::detect($value);
}

public static function flatten(IlluminateCollection $items): IlluminateCollection
protected static function collect(): IC
{
return Collection::make();
}

protected static function flatten(IC $items): IC
{
return Collection::flatten($items);
}

public static function resolveValue(mixed $value, string $column): Stringable
protected static function resolveValue(mixed $value, string $column): Stringable
{
return Resolver::value($value, $column);
}
Expand Down
Loading

0 comments on commit 3f39d59

Please sign in to comment.