0

Good day,

So I have the following array to start with that has items added to it. The order the items are added in the list have no specific sort to them to begin with other than the order they were originally added to the array in. For ease of reading, I put them in descending order to explain the result I am looking for. The values share a sub key of "tid" for this example.

Array
(
    [0] => Array
        (
            [tid] => value_5
        )

    [1] => Array
        (
            [tid] => value_4
        )

    [2] => Array
        (
            [tid] => value_3
        )

    [3] => Array
        (
            [tid] => value_2
        )

    [4] => Array
        (
            [tid] => value_1
        )

)

I now want to be able to feed a second array into a function, and have the array resorted so that the values supplied, which correlates to the "tid" of the field, are resorted to the front of the array in the order which they are given, and then leave the rest of the array in the order it currently is. For example, if I pass the following array as a sort key:

array("value_2", "value_3");

Then the value_2 and value_3 rows should become array key 0 and 1 respectively, but the rest of the array should stay in the same order like the following

Array
(
    [0] => Array
        (
            [tid] => value_2
        )

    [1] => Array
        (
            [tid] => value_3
        )

    [2] => Array
        (
            [tid] => value_5
        )

    [3] => Array
        (
            [tid] => value_4
        )

    [4] => Array
        (
            [tid] => value_1
        )

)

Alternatively, if a value that doesn't exist like value_9 is passed in the second array, we would just want to ignore that and skip past it.

I have explored a few options like a foreach and for loop and compared the values but its slow and doesn't really have recursion which seems like may be needed on this function.

As array sorting is a hot topic in PHP due to the myriad of ways to do so, I am looking to you guys for the best way to handle this problem. Thanks!

Kaboom
  • 674
  • 6
  • 27
  • 1
    We already have pages that demonstrate how to custom sort an array with PHP. [My answer](https://stackoverflow.com/a/48577805/2943403) is more performant than the accepted one. – mickmackusa May 15 '22 at 08:08

1 Answers1

0

If I understood correctly your problem, here's a possible solution:

$firstArray = [
    [ 'tid' => 'value_5' ],
    [ 'tid' => 'value_4' ],
    [ 'tid' => 'value_3' ],
    [ 'tid' => 'value_2' ],
    [ 'tid' => 'value_1' ],
];

$tidToAdd = [ 'value_2', 'value_3', 'value_9' ];

// The solution is below:

$intersect = array_intersect(array_column($firstArray, 'tid'), $tidToAdd);

$firstArrayFiltered = array_filter($firstArray, fn($elem) => !in_array($elem['tid'], $intersect));

$result = array_reduce($intersect, function($payload, $item) {
    array_unshift($payload, ['tid' => $item]);
    return $payload;
}, $firstArrayFiltered);
Dan
  • 3,329
  • 2
  • 21
  • 28
  • Almost perfect @Dan, the only issue is this creates a new variable at the top like it's supposed too, but it keeps the original in its place as well. Once 'value_2' and 'value_3' get moved, we should remove them from the end of array completely so they're not repeated. Then this is perfect! – Kaboom May 15 '22 at 05:29
  • 1
    I didn't get that part. I just changed the code :) – Dan May 15 '22 at 06:25
  • I very much do not endorse this very over-engineered sorting snippet. – mickmackusa May 15 '22 at 08:04
  • 1
    @mickmackusa if you explain why then it can be more helpful to improve the answer. – Dan May 15 '22 at 12:20
  • There are so many iterating function calls that I can't even calculate the time complexity of your advised solution. I can't even follow if the logic is trustworthy. See my answer on the duplicate to see an efficient and reliable solution. – mickmackusa May 15 '22 at 13:25
  • 1
    @mickmackusa your answer there is not applicable here because the problem is different. In my opinion this question is not a duplicate. I suggest you to try to write a solution to understand the problem and so to understand why there are so many iterations as well. – Dan May 15 '22 at 13:47
  • Or maybe I understand this question better than you do, it is an exact duplicate, and my suggestion works perfectly? https://3v4l.org/b8mmS – mickmackusa May 15 '22 at 20:38
  • Actually you’re wrong mick - his handles the errors of it not existing if you put in a value that’s not found while yours will throw an error in php 8.0+. – Kaboom May 15 '22 at 21:26
  • @mickmackusa You are right, your solution is nicer and more efficient. Really thanks for the enlightenment :D – Dan May 16 '22 at 04:07
  • @Kaboom Please show me a demo link where my recommended technique fails. I don't think I can reproduce what you are describing (if I understand you at all). – mickmackusa May 16 '22 at 04:09