我正在使用php,但也欢迎非语言特定的答案。
我有几个对象数组,我想循环并按顺序输出。每个数组中都有不同类型的对象,但所有对象都有唯一的顺序属性。
例如:
$people = [{'name':'George','email':'George@test.com','order':'2'},{'name...];
$sandwiches = [{'type':'bacon','rating':'8/10','order':'1'},{'type...];
$restaurants = ....
$chefs = ...
...
按顺序循环遍历它们的最有效方法是什么?
假设我可以确定最大顺序,我认为我可以做类似的事情:
for($i=0; $i< $maximumOrder; $i++)
{
for($j=0; $j< count($people); $j++)
{
if($people[$j]->order == $i)
{
//Do the things I want to do
break;
}
}
for($j=0; $j< count($sandwiches); $j++)
{
if($sandwiches[$j]->order == $i)
{
//Do the things I want to do
break;
}
}
for($j=0; $j< count($restaurants); $j++)
{
.....
}
但这并不是很好,因为即使在人们中找到了具有所需顺序的项目,它仍将继续循环遍历所有其他数组。我可以添加一个布尔变量来显示是否已找到所需的项目(见下文),但我确信有更好的方法可以做到这一点。
for($i=0; $i< $maximumOrder; $i++)
{
$found = false;
for($j=0; $j< count($people); $j++)
{
if($people[$j]->order == $i)
{
//Do the things I want to do
$found = true;
break;
}
}
if(!$found == true)
{
for($j=0; $j< count($sandwiches); $j++)
{
if($sandwiches[$j]->order == $i)
{
//Do the things I want to do
$found = true;
break;
}
}
}
if(!$found == true)
{
for($j=0; $j< count($restaurants); $j++)
{
.....
}
以下是基于@Victory的答案,添加了一个elseif语句,如果它传递了所需的订单号,则停止while循环(假设这些是现在已排序的数组)。我相信这应该提高效率(至少对于大阵列),但如果我错了,请纠正我吗?
function orderArrayByOrder($a,$b)
{
return ($a->order < $b->order) ? -1 : 1;
}
$a1 = usort($people, "orderArrayByOrder");
$a2 = usort($sandwiches, "orderArrayByOrder");
$a3 = usort($restaurants, "orderArrayByOrder");
$c1 = count($a1)
$c2 = count($c2)
$c3 = count($c3)
$i1 = 0
$i2 = 0
$i3 = 0
// itertor over order
for ($curOrder ... $maxorder)
{
while ($i1 < $c1)
{
if($a1[$i1]->order == $curOrder)
{
//Do what I need to do
break;
}
elseif($a1[$i1]->order > $curOrder)
{
//We know the order won't exist in this array.
break;
}
$i1++;
}
while ($i2 < $c2)
{
if($a2[$i2]->order == $curOrder)
{
//Do what I need to do
break;
}
elseif($a2[$i2]->order > $curOrder)
{
break;
}
$i1++;
}
}
答案 0 :(得分:2)
基本上你需要对每个数组进行排序并找到maxorder,然后循环遍历订单索引并使用给定的顺序打印项目。这是O(N Log(N))
,因为N = max number of elements
这是一些伪代码
对每个数组进行排序(在php中使用usort) - O(N log(N))
找到maxorder(遍历每个) - O(N)
为每个索引创建一个数组
获取每个索引的长度并存储
$a1 = usort($people, function(){})
$a2 = usort($places, function(){})
$a3 = usort($things, function(){})
$c1 = count($a1)
$c2 = count($c2)
$c3 = count($c3)
$i1 = 0
$i2 = 0
$i3 = 0
// itertor over order
for ($curOrder ... $maxorder) {
// while $a1 is on current order and its index is in bound
while ($i1 < $c1 && $a1[$i1]->order == $curOrder) {
echo $a1[$i1]->value;
$i1++;
}
while ($i2 < $c2 && $a2->order == $curOrder) {
echo $a2[$i2]->value;
$i2++;
}
while ($i3 < $c3 && $a3->order == $curOrder) {
echo $a3[$i3]->value;
$i3++;
}
}
答案 1 :(得分:1)
如果按对象的顺序值重新索引每个数组,则可以在固定时间内检索具有给定顺序的对象。代码检索O(n)
中的所有相关对象,因为您正在查看每个元素的次数(注意嵌套循环已被删除)。
$peopleByOrder = array();
$sandwichesByOrder = array();
$restaurantsByOrder = array();
$uniqueOrderKeys = array();
foreach($people as $person) {
$peopleByOrder[$person->order] = $person;
$uniqueOrderKeys[$person->order] = 1;
}
// same for $sandwichesByOrder and $restaurantsByOrder
foreach(array_keys($uniqueOrderKeys) as $oderKey) {
if(isset($peopleByOrder[$orderKey])) {
$person = $peopleByOrder[$orderKey];
}
else if(isset($sandwichesByOrder[$orderKey])) {
$sandwich = $sandwichesByOrder[$orderKey];
}
else if(isset($restaurantsByOrder[$orderKey])) {
$restaurant = $restaurantsByOrder[$orderKey];
}
}