对 multidim 数组进行排序:如果列包含子字符串,则优先排序,然后按第二列排序
我目前正在创建一个由 mysql 查询中的值组成的排序方法。
下面是数组的简要视图:
Array
(
[0] => Array
(
['id'] = 1;
['countries'] = 'EN,CH,SP';
)
[1] => Array
(
['id'] = 2;
['countries'] = 'GE,SP,SV';
)
)
我已经成功地根据数字 id 值进行正常的 usort,但我更想按“countries”字段的内容对数组进行排序(如果它包含一组字符串、一个国家/地区)代码(在本例中),然后是 id 字段。
以下片段是我关于如何做到这一点的第一个想法,但我不知道如何将其合并到工作功能中:
in_array('EN', explode(",",$a['countries']) );
你会怎么做?
谢谢!
不幸的是,我真的一事无成。
这是我目前所拥有的,除了错误之外什么也没有: uasort() [function.uasort]: Invalid Comparison function
function compare($a, $b) {
global $usercountry;
if ( in_array($usercountry, $a['countries']) && in_array($usercountry, $a['countries']) ) {
$return = 0;
}
else if (in_array($usercountry, $a['countries'])) {
$return = 1;
}
else {
$return = -1;
}
return $return;
}
$array= usort($array, "compare");
有没有人可以给我提示如何继续与它?
I am currently creating a sorting method that consists of values from an mysql query.
Here's a brief view of the array:
Array
(
[0] => Array
(
['id'] = 1;
['countries'] = 'EN,CH,SP';
)
[1] => Array
(
['id'] = 2;
['countries'] = 'GE,SP,SV';
)
)
I have succeeded in making a normal usort based on the numeric id values, but I rather want to sort the array by the content of the "countries" field (if it contains a set string, a country code in this case), and then by the id field.
The following snippet was my first idea of how to do it, but I have no idea of how to incorporate it into an working function:
in_array('EN', explode(",",$a['countries']) );
How would you do it?
Thanks!
I am really getting nowhere with this unfortunately.
Here is what I have for the moment, and its giving me nothing but errors: uasort() [function.uasort]: Invalid comparison function
function compare($a, $b) {
global $usercountry;
if ( in_array($usercountry, $a['countries']) && in_array($usercountry, $a['countries']) ) {
$return = 0;
}
else if (in_array($usercountry, $a['countries'])) {
$return = 1;
}
else {
$return = -1;
}
return $return;
}
$array= usort($array, "compare");
Is there anyone who might give me a hint of how to go on with it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
就我个人而言,我会结合使用自定义(匿名)函数
usort ()
。编辑:重新你的评论。希望这会让您走上正轨。此功能对同时具有 EN 或均不具有 EN 的元素给予同等优先级,或者当只有一个具有 EN 时调整优先级。
另一方面,如果两者都具有 EN,则该函数给予相同的优先级,如果一个具有 EN,则给予更高的优先级,并且如果两者都没有 EN,则进行文本比较。
再次,希望这会给你足够的方向来独自前进。如果您有任何问题,请随时发表更多评论,我会尽力提供帮助。
如果您想将多个属性与权重进行比较,请注意:尝试使用时髦的开关块,例如#更多编辑!#
其实我更多地思考的是复杂排序的问题,我提出了以下解决方案,供大家参考。它将允许您根据国家索引中出现的关键字定义数字排名。下面是代码,包括一个示例:
示例数组
排序例程
注意:此代码会将排名最高的整体排序到数组的顶部 。如果您想要相反的行为,请将其更改为:
请
注意,大于号已更改为小于号。进行此更改将导致排名最低的条目被排序到数组顶部。希望这一切有帮助!
##另请注意!##
此代码将对您的数组进行一个小更改,因为它将 _score 元素添加到每个数组中。希望这不是问题,因为通过存储这个值,我实际上能够将速度提高一倍以上(在我的基准测试中,速度从 .00038-.00041 降至 .00016-.00018)。如果没有,则删除检索缓存值的
if
块,并让else
块的内容每次都执行,当然存储分数值的部分除外。顺便说一句,这是数组排序后的
var_export()
转储:享受吧!
Personally, I would use a custom (anonymous) function in conjunction with
usort()
.EDIT: Re - your comment. Hopefully this will put you on the right track. This function gives equal priority to elements which both have EN or neither have EN, or adjusted priority when just one has EN.
This function, on the other hand, gives equal priority if both have EN, higher if one has EN, and does a text comparison if neither has EN.
Again, hopefully this will give you enough direction to move forward on your own. If you are having any problems, feel free to post more comments and I'll try to help.
A note if you're tying to compare multiple properties with weight: try out a funky switch block, e.g.#More Edits!#
Actually, I was thinking more on the problem of complex sorting, and I have come up with the following solution, for your consideration. It will allow you to define numerical rankings based on keywords which would appear in the countries index. Here is the code, including an example:
Example Array
Sorting Routine
Note: This code will sort the highest ranking entires to the top of the array. If you want reverse behavior, change this:
to
Note that the greater-than was changed to a less-than symbol. Making this change will result in the lowest ranking entries being sorted to the top of the array. Hope all this helps!
##NOTE ALSO!##
This code will make a small change to your array, in that it adds the _score element to each array. Hopefully this is not a problem, as by storing this value I was literally able to increase speed by more than double (.00038-.00041 down to .00016-.00018 in my benchmarks). If not, remove the
if
blocks that retrieve the cached value and let the contents of theelse
blocks execute every time, except of course for the part which stores the score value.By the way, here's a
var_export()
dump of the array after it was sorted:Enjoy!
终于在 PHP.net 上找到了这个奇妙的功能:
每个国家都是这样的:
$array['countries'] = in_array($needle, $haystack);
感谢
大家的帮助!
Finally found this wonderful function at PHP.net:
This is how each country looks like:
$array['countries'] = in_array($needle, $haystack);
}
Thanks all for your help!
您可能会考虑
array_walk
和array_walk_recursive
和array_map
,组合在一起时可能会去做你想做的事。You might consider
array_walk
andarray_walk_recursive
andarray_map
, which when combined together maybe to get to doing what you want to do.真相:
使用 MySQL 以外的任何方式对结果集进行排序的效率都会较低(使用 php、
usort()
或array_multisort() 调用会更加复杂并且更难维护),因此不合适。
SQL: (演示)
这会优先考虑
countries
列包含EN
的值然后按id
ASC 排序。对于不处理 sql 结果集或由于某种原因无法操作查询的任何人,我认可
usort()
。PHP7 提供了一个漂亮的新运算符,它执行比较并返回三个值之一(-1、0、1)。该运算符被亲切地称为“宇宙飞船运算符”,看起来像这样的
<=>
。PHP:(演示)
PHP8 替代方案:
或
输出:
太空飞船运算符两侧的数组元素从从左到右(左侧 [0] 与右侧 [0],然后如果两个 [0] 值之间存在“平局”,则移至一对 [1] 值)。
如果
=== false
向后看,让我解释一下...如果在国家字符串中找到
EN
,则条件将评估为false
。比较true
和false
时,请记住true
等于 1,false
等于 0。我们需要 ASC 排序,因此我们希望将错误结果放在真实结果之前,因此包含EN
的字符串需要返回 false。希望这能澄清逻辑。TRUTH:
Using anything other than MySQL to sort your result set will be less efficient (with php, a
usort()
orarray_multisort()
call will be more convoluted and harder to maintain) and therefore inappropriate.SQL: (Demo)
This prioritizes
countries
column values that containEN
then sorts onid
ASC.For anyone who isn't handling a sql result set or cannot manipulate the query for some reason, I endorse
usort()
.PHP7 offers a beautiful new operator that performs a comparison and returns one of three values (-1, 0, 1). This operator is affectionately called the "spaceship operator" and looks like this
<=>
.PHP: (Demo)
PHP8 alternatives:
or
Output:
The array elements on either side of the spaceship operator are evaluated from left to right (leftside [0] vs rightside [0], then moving onto the pair of [1] values if there is a "tie" between the two [0] values).
If the
=== false
looks backwards, let me explain...If
EN
is found in the countries string, the condition will evaluate asfalse
. When comparingtrue
andfalse
, remember thattrue
equates to 1 andfalse
equates to 0. We want ASC sorting, so we want to put false outcomes before true outcomes, ergo strings containingEN
need to return false. Hopefully that clears up the logic.