2014-09-03 86 views
0

我希望这不是一个重复的问题;我已经搜索无济于事...PHP usort针对外部变量的对象数组

我想排序搜索返回的对象数组。我想按以下方式对结果进行排序:如果对象的“name”属性与搜索查询匹配,请将其放在顶部。接下来,如果“城市”属性与查询匹配,请将其放在下面。 (我打算稍后添加更多标准。)所以我并不严格比较值,而是将每个对象$a与搜索查询$q进行比较。该阵列确实正在重新编制索引,但不是按照我期望的顺序。我错过了什么?

function cmp($a, $b) { 
    global $q; // search query 

    $query = strtolower($q); 
    $name = strtolower($a->getName()); // defined in class 
    $city = strtolower($a->getCity()); // defined in class 

    if ($name == $query) { 
     return -1; 
    } 

    elseif ($city == $query) { 
     return -1; 
    } 

    return 0; 
} 

usort($cinemas, 'cmp'); // $cinemas is an array of objects 
+0

的CMP函数返回** 3 **东西的strcmp值:少(-1),等于(0),大于(+1)。你只返回两个东西:-1和0 – 2014-09-03 18:40:41

+0

嗯...我试着添加另一个elseif返回1,但结果仍然以相同的方式排列(匹配城市不在顶部)。 – 2014-09-03 18:56:01

+0

请给我一个你的'搜索查询'数组的例子。即数组('名称'=>'弗雷德','城市'=>'mycity')或者它是不同的格式?一些样本数据和预期结果可能有用。您的评论“匹配的城市不在顶部” - 我不确定这是怎么回事。 – 2014-09-03 19:01:10

回答

1

您需要比较两项在您的比较功能并返回哪一个更大。目前,你完全忽略了第二件物品被传入,$b。你的逻辑必须按此顺序:

  1. 如果a和b的名称相匹配的查询,他们是平等的
  2. 如果一个名称的查询相匹配,这是更大的
  3. 如果B的名称相匹配查询时,它大于
  4. 如果a和b的城市符合查询条件,他们是平等的
  5. 如果所在的城市的查询相匹配,这是更大的
  6. 如果b的城市查询相匹配,这是更大的
  7. 如果姓名和b的名字是不相等的,返回的两个
  8. strcmp值返回的城市和b的城市
0

您应该使用anonymous function

usort($cinemas, function($a, $b) use ($q) { 
    $query = strtolower($q); 
    $name = strtolower($a->getName()); // defined in class 
    $city = strtolower($a->getCity()); // defined in class 

    // do the comparison 
}); 

注意$q被导入函数的范围,所以没有必要为一个global

除此之外,该功能应返回10-1,如问题的评论中所述。

+0

'usort'函数需要返回**'3'**值中的一个:-1为'小于',+1为'大于';零等于'等于'。 – 2014-09-03 20:25:01

+0

谢谢,修复。 (虽然实际上'-1'和'1'通常就足够了。) – lxg 2014-09-03 21:27:07