0

I have a multidimensional array, that I need to sort after a given value (given from outside the array)

This is the array:

    array (
    [0] => array 
    (
        ["tfl_gpac_color"] => array([0] => "FF0000"),
        ["tfl_gpac_start"] => "1",
        ["tfl_gpac_end"] => "32"
    ),
    [1] => array
    (
        ["tfl_gpac_color"] => array([0] => "0000FF"),
        ["tfl_gpac_start"] => "33",
        ["tfl_gpac_end"] => "64"
    ),
    [2] => array
    (
        ["tfl_gpac_color"] => array([0] => "800080"),
        ["tfl_gpac_start"] => "65",
        ["tfl_gpac_end"] => "96"
    )
)

I also have a given value from a config,

$strStartNumber = '33';

The strStartNumber changes, and I want the array sorted by this value in comparison with the 'tfl_gpac_start'.

If the number is 33,I want the first entry to be the one, with the 33 from 'tfl_gpac_start', if the value is 65, it should be starting with the 'tfl_gpac_start' with the number 65.

For '33' like this (compared to the one above):

array (
[0] => array 
(
    ["tfl_gpac_color"] => array([0] => "0000FF"),
    ["tfl_gpac_start"] => "33",
    ["tfl_gpac_end"] => "64"
),

[1] => array
(
    ["tfl_gpac_color"] => array([0] => "800080"),
    ["tfl_gpac_start"] => "65",
    ["tfl_gpac_end"] => "96"
),
[2] => array
(
    ["tfl_gpac_color"] => array([0] => "FF0000"),
    ["tfl_gpac_start"] => "1",
    ["tfl_gpac_end"] => "32"
)

)

Thanks a lot for help, I tried several different ways, but I don't get it right...

EDIT: All values should be in the same place afterwards (should stay together), so the sort should only work on the key of the first array.

5
  • it isn't not fully clear how this sort works, how sort the others items? Do you want change only the item which matchs? Commented Dec 6, 2016 at 23:05
  • 1
    All other items should stay in the same order as original. See my example and the color array. To clarify: the items are for groups (have a color, a starting number, an end number). I just start every week with a different number, but the groups (color and so on), should be the same. Just the starting number changes. Thanks for your help. Commented Dec 6, 2016 at 23:32
  • You can't SORT with just one value that needs to be first - what about other groups then? From example it looks like you ROTATING the array - first element goes to last position untill required 33 is reached. Is that what you want? Commented Dec 7, 2016 at 0:39
  • so you just want to change the first item with the item which tfl_gpac_start equals $strStartNumber ? Commented Dec 7, 2016 at 0:49
  • @shudder Yes, that is exactly what I want. These are groups of people, that are called each week with a different starting number, so in theorie every group comes first after a few weeks. Commented Dec 7, 2016 at 10:10

3 Answers 3

0

To rotate an array you might use this loop:

while ($array[0]['tfl_gpac_start'] !== $strStartNumber) {
    $array[] = array_shift($array);
}

Note that these numeric values are strings - you need strict comparison ===/!==, because there are quirk cases with implicit string conversion that happens while comparing without type check. On the other hand if none value matches you'll get into infinite loop - i'd be careful with that either. You might add a couter to protect yourself:

$count = count($array);
while(... && $count--) {
    ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot, that did the trick. I had to change the type of $strStartNumber with strval, but otherwise worked like a charme!
0

You can't efficiently sort an array like that. However, depending on how you use your data and whether you can cache this, you can restructure your data.

For example, you could create an index table by using a foreach loop:

$index = [1 => 0, 33 => 1, 65 => 2];

Where 0, 1, 2 are the indexes in the original array. Then you can sort them:

ksort($index);

Now they are in order, and you can get all the data in your original array for $strStartNumber = 33 by getting $array[$index[$strStartNumber]]

When you need to get the one after it, you can get: $array[$index[$strStartNumber] + 1]

However, it looks like you might want it loop around, so if $strStartNumber = 65 then $array[$index[$strStartNumber] + 1] would not exist, but you would want the first entry in the list instead. You can get that with the same +1 by doing: $array[($index[$strStartNumber] + 1) % count($array)]

Comments

0

The algorithm you are after is

  1. Find the item
  2. Get the item and remove it
  3. Prepend the item to the top

NOTE: This code mutates the array

<?php
$strStartNumber = '33';
$array = array (
    0 => array 
    (
        "tfl_gpac_color" => array(0 => "FF0000"),
        "tfl_gpac_start" => "1",
        "tfl_gpac_end" => "32"
    ),
    1 => array
    (
        "tfl_gpac_color" => array(0 => "0000FF"),
        "tfl_gpac_start" => "33",
        "tfl_gpac_end" => "64"
    ),
    2 => array
    (
        "tfl_gpac_color" => array(0 => "800080"),
        "tfl_gpac_start" => "65",
        "tfl_gpac_end" => "96"
    )
);

$key = array_search($strStartNumber, array_column($array, 'tfl_gpac_start'));
if($key)
{
    $itm = array_splice($array, $key, 1);  
    array_unshift($array, $itm[0]);
}
?>
<pre><?php var_dump($array); ?></pre>

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.