【问题标题】:PHP custom sort function based on string occurence?基于字符串出现的PHP自定义排序功能?
【发布时间】:2013-11-21 08:42:21
【问题描述】:

假设我有一个数组:

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

我想usort这个符合以下条件:如果它包含tokyo排名第一,如果它包含tennis排名第二,如果它包含dog排名第三。

Place Tokyo,
Sport Tennis,
Animal Dog,
Subject Physics

我知道我可以使用stristr 来查看$a$b 中是否存在这些词,但我对编写3 if 条件一无所知...

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

我将如何编写比较函数?

【问题讨论】:

  • 您需要更精确地定义问题。 “如果它包含东京排名第一,如果它包含网球排名第二,等等......”所以这个排名也存储在有序数组中? ["tokyo", "tennis", "dog"] 那么"tokyo dog" < "tennis" 的结果应该是什么?
  • @mb21 不,排名不存储在数组中。我只想要三个 if 条件(更新了问题)。我没有完全理解你的最后一个问题?

标签: php sorting usort


【解决方案1】:

多么奇怪的问题.. 这是否符合您的要求?

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;
}

【讨论】:

  • 好答案。是否可以评论您的代码,或解释您使用按位或运算符的原因?谢谢!
  • 它只是为包含枚举单词的字符串分配权重。你可以使用+,它会做同样的事情
【解决方案2】:

试试这个代码。

$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"]

或者这个

$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"]

【讨论】:

  • 我喜欢你很好地记录了这一点。更容易理解。
  • @andrewk,检查第二个 :^)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多