How to sort a list of data classes by multiple columns in PHP

3 Answers

0 votes
class Item
{
    public int $a;
    public int $b;
    public string $label;

    public function __construct(int $a, int $b, string $label)
    {
        $this->a = $a;
        $this->b = $b;
        $this->label = $label;
    }

    public function __toString(): string
    {
        return "({$this->a}, {$this->b}, {$this->label})";
    }
}

// Create dataset
function makeData(): array {
    return [
        new Item(7, 2, "python"),
        new Item(8, 3, "c"),
        new Item(3, 5, "c++"),
        new Item(4, 1, "c#"),
        new Item(3, 2, "java"),
        new Item(7, 1, "go"),
        new Item(1, 2, "rust"),
    ];
}

// Sort by A then B
function sortData(array &$data): void
{
    usort($data, function (Item $x, Item $y) {
        if ($x->a !== $y->a) {
            return $x->a <=> $y->a;
        }
        return $x->b <=> $y->b;
    });
}

// Print all items
function printData(array $data): void
{
    foreach ($data as $item) {
        echo $item . PHP_EOL;
    }
}

// Find first item by label
function findByLabel(array $data, string $label): ?Item
{
    foreach ($data as $item) {
        if ($item->label === $label) {
            return $item;
        }
    }
    return null;
}

// Filter by A
function filterByA(array $data, int $value): array
{
    return array_filter($data, fn(Item $i) => $i->a === $value);
}

// Main
$data = makeData();

sortData($data);
echo "Sorted data:\n";
printData($data);

echo "\nSearching for 'java':\n";
$found = findByLabel($data, "java");
if ($found !== null) {
    echo $found . PHP_EOL;
}

echo "\nFiltering items where A = 7:\n";
$filtered = filterByA($data, 7);
printData($filtered);




/*
run:

Sorted data:
(1, 2, rust)
(3, 2, java)
(3, 5, c++)
(4, 1, c#)
(7, 1, go)
(7, 2, python)
(8, 3, c)

Searching for 'java':
(3, 2, java)

Filtering items where A = 7:
(7, 1, go)
(7, 2, python)

*/

 



answered Jan 29 by avibootz
0 votes
readonly class Item
{
    public function __construct(
        public int $a,
        public int $b,
        public string $label
    ) {}
}

function makeData(): array
{
    return [
        new Item(7, 2, "python"),
        new Item(8, 3, "c"),
        new Item(3, 5, "c++"),
        new Item(4, 1, "c#"),
        new Item(3, 2, "java"),
        new Item(7, 1, "go"),
        new Item(1, 2, "rust"),
    ];
}

function sortData(array &$data): void
{
    usort($data, function (Item $x, Item $y) {
        return [$x->a, $x->b] <=> [$y->a, $y->b];
    });
}

function printData(array $data): void
{
    foreach ($data as $item) {
        echo "({$item->a}, {$item->b}, {$item->label})\n";
    }
}


$data = makeData();

sortData($data);
printData($data);



/*
run:

(1, 2, rust)
(3, 2, java)
(3, 5, c++)
(4, 1, c#)
(7, 1, go)
(7, 2, python)
(8, 3, c)

*/

 



answered Jan 29 by avibootz
0 votes
enum Item: string
{
    case Python = 'python';
    case C = 'c';
    case Cpp = 'c++';
    case CSharp = 'c#';
    case Java = 'java';
    case Go = 'go';
    case Rust = 'rust';

    public function makeData(): array
    {
        return match($this) {
            self::Python => [7, 2],
            self::C      => [8, 3],
            self::Cpp    => [3, 5],
            self::CSharp => [4, 1],
            self::Java   => [3, 2],
            self::Go     => [7, 1],
            self::Rust   => [1, 2],
        };
    }
}

function buildData(): array
{
    $result = [];
    foreach (Item::cases() as $case) {
        [$a, $b] = $case->makeData();
        $result[] = (object)[
            'a'     => $a,
            'b'     => $b,
            'label' => $case->value,
        ];
    }
    return $result;
}

function sortData(array &$data): void
{
    usort($data, function ($x, $y) {
        return [$x->a, $x->b] <=> [$y->a, $y->b];
    });
}

function printData(array $data): void
{
    foreach ($data as $item) {
        echo "({$item->a}, {$item->b}, {$item->label})\n";
    }
}

$data = buildData();

sortData($data);
printData($data);



/*
run:

(1, 2, rust)
(3, 2, java)
(3, 5, c++)
(4, 1, c#)
(7, 1, go)
(7, 2, python)
(8, 3, c)

*/

 



answered Jan 29 by avibootz

Related questions

...