【发布时间】:2016-08-24 06:53:44
【问题描述】:
我必须对一个名为“内容”的对象数组进行排序,如下所示:
"articles" => array:106 [▼
0 => array:5 [▼
"id" => 467823568
"title" => "my tittle"
"data" => "my data"
"category" => 23
"order" => 2
]
1 => array:5 [▼
"id" => 46782356433
"title" => "my tittle 2"
"data" => "my data 2"
"category" => 25
"order" => 1
]
...
]
顺序定义在 2 个数组中,category_o 和 order_o 如下:
"category_o" => array:21 [▼
0 => 25
1 => 95
2 => 135
3 => 72
4 => 4
5 => 23
6 => 7
7 => 803
...
]
我希望文章按属性“类别”和category_o 数组中指定的自定义顺序排序,然后再按属性“顺序”和order_o 中指定的其他自定义顺序进行第二次排序。
我使用uasort方法对文章进行排序:
// Call sort function
uasort($articles, array($this, "sortByCategoryOrder"));
使用我的自定义函数sortByCategoryOrder($left, $right);:
function sortByCategoryOrder($leftItem, $rightItem){
// Array that contains order
$order = $this->category_o;
// Exchange key with value, so we can access "position by value"
$flipped = array_flip($order);
// Init default value for position
$rightPos = 0;
$leftPos = 0;
// Check if order of current category is present:
// the $category_o array could not have all order
// values of articles
if ( (array_key_exists($leftItem["category"], $flipped)) && (array_key_exists($rightItem["category"], $flipped)) ){
// NO MISSING: the 2 element have order
$leftPos = $flipped[$leftItem["category"]];
$rightPos = $flipped[$rightItem["category"]];
}else if (array_key_exists($leftItem["category"], $flipped)) {
// MISS RIGHT: the right elmenet has not custom order specified!
$leftPos = $flipped[$leftItem["category"]];
$rightPos = $leftPos+1;
}else if (array_key_exists($rightItem["category"], $flipped)){
// MISS LEFT: the left elmenet has not custom order specified!
$rightPos = $flipped[$rightItem["category"]];
$leftPos = $rightPos+1;
}else{
// MISS LEFT AND RIGHT: the 2 articles have no custom order specified!
$rightPos = 99999;
$leftPos = 99999;
}
// Make the comparation
return $leftPos >= $rightPos;
}
我还有一个名为 sortByOrder($left, $right); 的函数,它按 order_o 数组值对文章进行排序。
排序大约需要 12 秒。 2000 篇文章。
uasort 真的很慢还是我在自定义订单功能中犯了一些错误?
谢谢
解决方案:
感谢@Ahmad Hajjar,我找到了正确的解决方案。
我编写了另一种方法,为每个内容设置新属性category_o 和order_o,并使用双自然升序 和php 的方法array_multisort()。
性能提升和当前 2000 篇文章 传递 来自 ca。大约 9 秒1 秒!
我报告我的新方法,希望它是有希望的:
public function sortArticles($articles, $type)
{
// init sorted
$sorted = array();
// Array that contains order
$order_c = $this->category_o;
// Exchange key with value, so we can access "position by value"
$flipped_c = array_flip($order_c);
// Array that contains order
$order_o = $this->order_o;
// Exchange key with value, so we can access "position by value"
$flipped_o = array_flip($order_o);
// Iterate each article
foreach ($articles as $article) {
// If custom order was specified set it to article
// Otherwise, set 99999 value.
if ( array_key_exists( $article["category"], $flipped_c) ){
$article["category_o"] = $flipped_c[$article["category"]];
}else{
$article["category_o"] = 99999;
}
// If custom order was specified set it to article
// Otherwise, set 99999 value.
if ( array_key_exists($article["order"], $flipped_o) ){
$article["order_o"] = $flipped_o[$article["order"]];
}else{
$article["order_o"] = 99999;
}
// Push new article inside array
array_push($sorted, $article);
}
// get a list of sort columns and their data to pass to array_multisort
$sort = array();
foreach($sorted as $key => $value) {
$sort['order_o'][$key] = $value['order_o'];
$sort['category_o'][$key] = $value['category_o'];
}
// Determinate order type, category or order
if (strcmp($type, "category") == 0) {
// sort by category_o asc and then order_o asc
array_multisort($sort['category_o'], SORT_ASC, $sort['order_o'], SORT_ASC,$sorted);
}else{
// sort by order_o asc and then category_o asc
array_multisort($sort['order_o'], SORT_ASC, $sort['category_o'], SORT_ASC,$sorted);
}
// Return sorted array
return $sorted;
}
【问题讨论】:
-
如果文章存储在数据库中,为什么不按您需要的任何字段从数据库中获取它们?
标签: php arrays performance sorting