0

Lets say I have the following data:

$data = array('av','ds','tg','ik','pk','np','rq');

I'm having trouble finding out what tools to use to get the range of strings between two variables.

function sortrange ( $a, $b, $data )
{
    return $range;
}

For example:

sortrange('ds','np', $data);

Would return

array('ds','tg','ik','pk','np');

I would also like it be able to do backwards sorting, for example:

sortrange('np','tg');

Would return:

array('np','pk','ik','tg');

The closest function I found that might be usable was usort, but it couldn't get anywhere close to what I wanted.

Thanks for any help in advance. :)

2
  • I don't see where you need anything sorting - it looks like you want to return a subset of the array. Commented Jul 3, 2011 at 14:26
  • Well, I thought that the fact that I need a function that returns the array backwards depending on the order of the arguments counted as sorting. Commented Jul 3, 2011 at 14:30

2 Answers 2

1

Note: The following function will just use the first occurance of $start and $end. If they repeat, the behavior may not be what you expect.

function subset_range($array, $start, $end) {
    $start_index = array_search($start, $array);
    $end_index = array_search($end, $array);
    $min = min($start_index, $end_index);
    $max = max($start_index, $end_index);
    $ret = array_slice($array, $min, $max - $min + 1);
    return $start_index < $end_index ? $ret : array_reverse($ret);
}

$data = array('av','ds','tg','ik','pk','np','rq');

print_r(subset_range($data, 'ds', 'np'));
print_r(subset_range($data, 'np', 'tg'));

Output:

Array
(
    [0] => ds
    [1] => tg
    [2] => ik
    [3] => pk
    [4] => np
)
Array
(
    [0] => np
    [1] => pk
    [2] => ik
    [3] => tg
)
Sign up to request clarification or add additional context in comments.

4 Comments

+1. @OP: Note, the elements are practically required to be unique. If they aren't unique, you might not get the range you expect. But that'll be true of any solution you may find.
For this particular problem, they are unique. Thanks for the heads up though :) Also curious as to why you picked this answer rather than Adam's?
@Tek: Adam's answer is more complicated than it has to be. I like simplicity, if it produces the correct answer. (At the time of this comment, it also appears to have a bug or two. The very reason i prefer keeping it simple. :) )
@Tek: Also note, though, Adam's answer does one thing that this one doesn't: it makes sure the endpoints actually exist in the array. It's up to you whether this is necessary, and what the return value should be if they don't exist...but i'd consider something similar to what he did, iff i couldn't guarantee the endpoints were in the array.
0

Something like this:

function get_subset($a, $b, $data) {
    // fail if $a or $b is not present in $data
    if(in_array($a) === false || in_array($b) === false) {
        return false;
    }
    // get the index of both $a and $b
    $i_a = array_search($a, $data);
    $i_a = array_search($b, $data);
    $result = array();
    if($i_a < $i_b) {
        // if $a is earlier than $b in $data, loop forward
        for($i = $i_a; $i <= $i_b; $i++) {
            $result[] = $data[$i];
        }
    } elseif($i_a > $i_b) {
        // if $a is later than $b in $data, loop backward
       for($i = $i_a; $i <= $i_b; $i--) {
            $result[] = $data[$i];
        }
    } else {
        // if $a and $b are the same
        return array($a, $b);
    }
    return $result;
}

2 Comments

If $i_a > $i_b, it looks to me that the loop will never run. (You're checking whether $i <= $i_b, when if it starts at $i_a, you just guaranteed it'll be greater.)
Also, if $i_a == $i_b, then the array should probably have one element ($a and $b are the same element). You're returning two.

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.