List 用Perl在O(n)中自定义列表的重新排序/排序
我正在重新订购一份清单 我的原始列表,输入:@lineItemsList 用Perl在O(n)中自定义列表的重新排序/排序,list,perl,sorting,reference,List,Perl,Sorting,Reference,我正在重新订购一份清单 我的原始列表,输入:@lineItems [ {id=> 'id1', ..}, {id=> 'id2', 'groupId'=>45D,.. }, {id=> 'id3', 'groupId'=>56A, .. }, {id=> 'id4', 'groupId'=>45D, 'isParent'=>1 .. }, {id=> 'id5', ..}, {id=> 'id6', 'group
[
{id=> 'id1', ..},
{id=> 'id2', 'groupId'=>45D,.. },
{id=> 'id3', 'groupId'=>56A, .. },
{id=> 'id4', 'groupId'=>45D, 'isParent'=>1 .. },
{id=> 'id5', ..},
{id=> 'id6', 'groupId'=>56A, 'isParent'=>1.. },
]
在上面的列表中,groupId表示该项是bundle的一部分。GroupId唯一地确定捆绑组。如果组Id不存在,则其为非捆绑项
目标-对列表重新排序,以便在每个捆绑包的开始处,所有捆绑包项目都应与父项目一起分组,并且捆绑包和非捆绑包项目的传入顺序(当groupId不存在时)应保持不变。
按O(n)对列表进行排序
预期产出:
[
{id=> 'id1', ..},
{id=> 'id4', 'groupId'=>45D, 'isParent'=>1 .. },
{id=> 'id2', 'groupId'=>45D,.. },
{id=> 'id6', 'groupId'=>56A, 'isParent'=>1.. },
{id=> 'id3', 'groupId'=>56A, .. },
{id=> 'id5', ..},
]
这是我的算法:
my $grouIdToLineItemIdMap;
foreach my $lineItem (@$lineItems) {
if(!$lineItem->{'groupID'}) { #non bundle item, add as it is
push @sortedLineitemsIds, $lineItem->{'id'};
} else {
if($lineItem->{'IsParent'} eq 1) {
unshift @{$grouIdToLineItemIdMap->{$groupId}}, $lineItem->{'id'};
} else {
push @{$grouIdToLineItemIdMap->{$groupId}}, $lineItem->{'id'};
}
}
}
push @sortedLineitemsIds, $grouIdToLineItemIdMap; # **[[Question 1]]** This will always add bundle items at the end irrespective of whether it was in starting or end.
现在这将产生sortedLineitemsIds=>
$VAR1 = [
'id1',
'id5',
{
'45D' => [
'id4:',
'id2:'
],
'56A' => [
'id6:',
'id3:'
]
}
];
第2条代码
foreach my $Id (@sortedLineitemsIds) {
if(determineIfSingleIdOrMapOfGroupId) { #**[[Question 2]]**
my $lineItem = grep @lineItems with $Id; #**[[Question 3]]**
push @sortedLineItems, $lineItem;
} else {
my $listOfLineItemsForGroupId = $sortedLineitemsIds->{$Id};
foreach groupLineItemId (@$listOfLineItemsForGroupId) {
my $lineItem = grep @lineItems with groupLineItemId; #**[[Question 3]]**
push @sortedLineItems, $lineItem;
}
}
}
我现在有3个问题在代码的不同位置标记:
你说你不想改变物品的顺序,但这显然不是真的。我想你的意思是: 我想保留项目的相对顺序,这些项目要么是独立的,要么是它们组中的第一个 这确实可以在O(N)中完成 我们要建造这个:
my@grouped=(
[$lineItem_id1],
[$lineItem_id4,$lineItem_id2],
[$lineItem_id6,$lineItem_id3],
[$lineItem_id5],
);
为了实现这一点,我们将使用以下算法:
@grouped
@grouped
my$group_45D=[$lineItem_id4,$lineItem_id2];
我的$group_56A=[$lineItem_id6,$lineItem_id3];
我的%groups=(
“45D”=>$group_45D,
“56A”=>$group_56A,
);
我的@grouped=(
[$lineItem_id1],
$45D组,
$group_56A,
[$lineItem_id5],
);
解决方案:
my@grouped;
{
我的%组;
对于我的$lineItem(@$lineItems){
if(my$groupId=$lineItem->{groupId}){
if(!$groups{$groupId}){
push@grouped,$groups{$groupId}=[];
}
如果($lineItem->{isParent}){
取消移位@{$groups{$groupId},$lineItem;
}否则{
push@{$groups{$groupId}},$lineItem;
}
}否则{
推送@grouped,[$lineItem];
}
}
}
最后,我们只需要将列表展平
my@ordered=map{@$}@grouped;
已测试。此处您不能将组的父项作为该组的第一项。我们需要检查它是否是父对象,然后在前面添加。和id4一样,虽然它在相对顺序上排在后面,但由于它的父代在id2之前。我们如何才能做到这一点?另外,你是说我们可以在一个循环中完成这项工作?分组变量是映射吗?那我们可以用“推”操作符吗?我看到你正在使用“分组”作为地图和列表。不确定你是否能在perl中做到这一点。很抱歉提出一些愚蠢的问题,但我对perl.Correct非常陌生。如果“%grouped”是一个散列,我在这里得到一个错误:push@grouped,$grouped{$groupID}=[];另外,在哪里使用了%组?我在这里感到困惑。我们可以在聊天中进行讨论吗?