Question

Finding the right title for this was next to impossible.

Imagine this scenario:

We have an array that contains certain product tags. The key is each tag's unique id and the value is its label:

Available Tags

Array (
  [3] => Sweet
  [4] => Sour
  [5] => Bitter
  [6] => Winter
  [7] => Organic
)

We have another array which contains the tags that have been selected. The selection has a specific order which is defined by the key, while the value represents the id (of the actual tag we see in array #1).

Selected Tags in Specific Order

Array (
  [10] => 4
  [20] => 3
  [30] => 7
)

My theoretical Approach

Certainly i could go about foreach-ing through the second array, collecting the appropriate values (that correspond to the first array's entries) in a new array. Then i could iterate over the first array and add all the values (to the new array) which are not yet present in the new array.

Quite honestly - that doesn't feel very professional. Unfortunately, i have no idea how to do this better.

Question

How can i neatly sort the first array (Available Tags) by using the chronology defined by the second array (Selected Tags)?

Note

I want to end up with all items from the first array. Not just the ones that are listed in the second one.

In case someone's curious: this is for multiple-selects which are sortable. Items which have been selected are sortable and must therefore appear in the right order. The other items order doesn't matter. My server-side data handler class gives me these two arrays as described, so that's what i got to work with.

Was it helpful?

Solution

Here's a solution that uses uksort(). Elements of the $tags array that are not present in the $order array are sorted to the end, and the relative order between them is undefined.

function my_sort($a, $b) {
    global $order;

    if(in_array($a, $order)) {
        if(in_array($b, $order)) {
            // Both $a and $b have an order
            return array_search($a, $order) - array_search($b, $order);
        }
        else {
            // Only $a has an order, so it goes before $b
            return -1;
        }
    }
    else if(in_array($b, $order)) {
        // Only $b has an order, so it goes before $a
        return 1;
    }
    else {
        // Neither $a or $b has an order, so we don't care how they're sorted
        return 0;
    }
}

uksort($tags, 'my_sort');

OTHER TIPS

I think you can just loop in your second array and build a new one using keys

$new = array();
foreach($array2 as $key => $val)
{
    $new_array[] = $array1[$val];
}

Now the selected items are ordered in your $new_array

Sample

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top