2

I'm using usort to sort an array of objects, but really I want this to act as a kind of "group by" function without disturbing the original relative order of the rows.

Say I have this:

MASTER_CODE, CONFIG_ITEM
foo1, opt_ray
foo2, opt_ray
foo1, opt_fah
foo2, opt_doe

From that data, an array of objects is constructed with an anonymous key. That is, each row is parsed as an object. The objects are collected into an array.

What I want to do is sort the array by the MASTER_CODE value, but without disturbing the order.

That is, the final order should be:

MASTER_CODE, CONFIG_ITEM
foo1, opt_ray
foo1, opt_fah
foo2, opt_ray
foo2, opt_doe

We don't add a sort order, because the data comes from an external source.

I can use usort to order by the master code, but it messes up the original relative order.

Any suggestions?

Tim
  • 197
  • 1
  • 1
  • 10

1 Answers1

0

This is one option - it's not the most elegant solution. It will take the unique values from the first column of your array (the one you want to filter by), sort that, then loop it and add entries from your original array with the same first value.

// Get an unique array of values to use for sorting
$sorting = array_unique(array_column($a, 0));
sort($sorting);

$sorted = [];
foreach ($sorting as $sortValue) {
    $sorted = array_merge(
        $sorted,
        array_filter(
            $a,
            function($row) use ($sortValue) {
                // Find values that have the same first value as each sort value
                return ($sortValue === $row[0]);
            }
        )
    );
}

Example

Note: This will work on PHP 5.5. Since you also tagged PHP 5.3, you may need to replace the array_column function. Try something like this:

$sorting = array_unique(array_map(function($row) { return $row[0]; }, $a));
scrowler
  • 24,273
  • 9
  • 60
  • 92
  • It's good thinking, but its important to remember that its an array of Objects, not an array of arrays. Each row of data is parsed as an object. These objects are accumulated into an array. – Tim Nov 21 '16 at 00:30
  • Sure. Can you post a `var_export` of the actual object so I can take another look? – scrowler Nov 21 '16 at 00:31
  • Unfortunately I can't give you an export as its sensitive data. – Tim Nov 21 '16 at 00:46
  • Right. Well as a bit of a hack you could [force the object to an array](https://eval.in/681380) – scrowler Nov 21 '16 at 00:48
  • 1
    Huh... it's just occurred that I can add a sortorder param to the object during load/parse. That would embed the original order in the object, and I can include that in my usort... – Tim Nov 21 '16 at 00:58