3

Say I have an arrray:

$arr = array(
  'Animal Dog',
  'Subject Physics',
  'Place Tokyo',
  'Sport Tennis'
);

I want to usort this with the following criteria: if it contains tokyo rank first, if it contains tennis rank second, if it contains dog rank third.

Place Tokyo,
Sport Tennis,
Animal Dog,
Subject Physics

I know I can use stristr to see if the words exist in $a and $b, but I'm clueless on writing the 3 if conditions...

function cmp($a,$b){
 if ( stristr($a,'tokyo') )
  // return what?
}
usort($arr, "cmp")

How would I go about writing the comparison function?

2
  • 1
    You need to be more precise with the problem definition. "if it contains tokyo rank first, if it contains tennis rank second, etc..." so this ranking is stored in an ordered array as well? ["tokyo", "tennis", "dog"] What should be the result of "tokyo dog" < "tennis" then? Commented Nov 20, 2013 at 22:46
  • @mb21 no, the ranking isn't stored in an array. I just want three if conditions (updated the question). I didn't fully understand your last question? Commented Nov 20, 2013 at 23:08

2 Answers 2

2

what a strange question.. does this do what you're looking for?

usort($arr, 'cmp');
function cmp($a, $b) {
    $av = (stripos($a, 'tokyo') !== false) * 4 | (stripos($a, 'tennis') !== false) * 2 | (stripos($a, 'dog') !== false);
    $bv = (stripos($b, 'tokyo') !== false) * 4 | (stripos($b, 'tennis') !== false) * 2 | (stripos($b, 'dog') !== false);
    return $av < $bv;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Good answer. Is it possible to comment your code, or explain why you are using the bitwise or operator? Thanks!
it's just assigning weight to strings that contain the enumerated words. you could use + and it would do the same thing
2

Try this code.

$arr = array(
    'Animal Dog3',
    'Animal Dog1',
    'Animal Dog2',
    'Subject Physics',
    'Place1 Tokyo',
    'Place4 Tokyo',
    'Sport Tennis'
);

$order_array = array('tokyo', 'tennis', 'dog');
$sort_function = function($a, $b) use($order_array)
        {
        $return = strcasecmp($a, $b);
        foreach ($order_array as $word)
            {
            // if each string contains `tokyo` -- alphabetical order
            if (stripos($a, $word) !== false && stripos($b, $word) !== false)
                {
                $return = strcasecmp($a, $b);
                break;
                }
            // if $a string contains `tokyo` -- $a goes first
            elseif (stripos($a, $word) !== false)
                {
                $return = -1;
                break;
                }
            // if $b string contains `tokyo` -- $b goes first
            elseif (stripos($b, $word) !== false)
                {
                $return = 1;
                break;
                }
            // if $a and $b does not contains -- lets take `tennis`
            else
                {
                continue; // just for readablity
                }
            }
        return $return;
        };

usort($arr, $sort_function);
var_dump($arr);
// ["Place1 Tokyo","Place4 Tokyo","Sport Tennis","Animal Dog1","Animal Dog2","Animal Dog3","Subject Physics"]

Or this one

$arr = array(
    'Animal Dog3',
    'Animal Dog1',
    'Animal Dog2',
    'Subject Physics',
    'Place1 Tokyo',
    'Place4 Tokyo',
    'Sport Tennis'
);
$order_array = array('tokyo', 'tennis', 'dog');
$sort_function = function($a, $b) use($order_array)
        {
        $a_index = sizeof($order_array); // lets suppose that it's last
        $b_index = sizeof($order_array); // lets suppose that it's last
        $i = 0;
        foreach ($order_array as $word)
            {
            if (stripos($a, $word) !== false)
                $a_index = $i;           // remeber index order of $a
            if (stripos($b, $word) !== false)
                $b_index = $i;           // remeber index order of $b
            $i++;
            }

        if ($a_index == $b_index)      // if indexes are equal
            return strcasecmp($a, $b); // alphabetical order
        else
            return $a_index - $b_index; // index order
        };

usort($arr, $sort_function);
var_dump($arr);
// ["Place1 Tokyo","Place4 Tokyo","Sport Tennis","Animal Dog1","Animal Dog2","Animal Dog3","Subject Physics"]

2 Comments

I like that you documented this very well. Much easier to understand.
@andrewk , check second one :^ )

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.