0

I have an array of numeric subarrays. I want to sort all the subarrays, and then sort the whole array, and remove duplicates. Using sort($val) doesn't work, so I found the following workaround with $derp, which I find insanely stupid:

$arr = array( array(5,6), array(1,2), array(6,5) );
foreach ($arr as $key => $val) {
    $derp = $val;
    sort($derp);
    $arr[$key] = $derp;
}
sort($arr);
$arr = array_map("unserialize", array_unique(array_map("serialize", $arr)));

The result is array( array(1,2), array(5,6) ). Is that is the correct way to do this in PHP, or is there a better and shorter way?

I created a pastebin as a response to the first answer: pastebin.com/Y5vNvKKL
This question is not anymore just about a less goofy way to write this: Now the question is:
Why does sort() in array_work() not give the same result as sort() in foreach?

By the way: This is about finding the partitions of multisets.

2 Answers 2

1

I'd approach it like this:

array_walk($arr, fn (&$value) => sort($value));

$deduped = array();
foreach ($arr as $val) {
    $deduped[serialize($val)] = $val;
}

$arr = array_values($deduped);
Sign up to request clarification or add additional context in comments.

5 Comments

array_walk() was what I was looking for, thanks. BTW, your code gives array( array(5,6), array(1,2) ).
Actually this doesn't always work in the same way as the $derp version. This may have to do with the fact, that my array contains not only arrays, but also single numbers. See pastebin.com/Y5vNvKKL
I mean: This may have to do with the fact, that the subarray contain not only single numbers, but also arrays. However, it is weird, because the code suggests that we do the same in both cases: Apply sort() to all subarrays. But the result is not the same.
array_walk($array, 'sort') must not be recommended for general-use because the keys parameter in the callback of array_walk will funk with sorts second parameter. Proof can be seen in keyed rows 2, 5, 10, and 13 here: 3v4l.org/Yn9mc
0

array_unique($array, SORT_REGULAR) is quite convenient for filtering whole rows of a 2d array, but it respects associative relationships when checking for uniqueness. Demo

$array = [[5, 6], [1, 2], [6, 5], [1, 2], [1 => 2, 0 => 1]];

var_export(
    array_unique($array, SORT_REGULAR)
);

Output: [[5, 6], [1, 2], [6, 5]]

Feed sorted rows to that technique and everything works out as expected. Demo

var_export(
    array_unique(
        array_map(
            function ($row) {
                sort($row);
                return $row;
            },
            $array
        ),
        SORT_REGULAR
    )
);

Output: [[5, 6], [1, 2]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.