我的原型中的重复字段中有一些条目。现在我要删除其中一些。我怎么能做到这一点?有一个删除最后一个元素的函数,但我想删除任意元素。我不能交换它们,因为订单很重要。
我可以与下一个交换直到结束,但是没有更好的解决方案吗?
答案 0 :(得分:11)
根据API docs,没有办法从重复字段中任意删除元素,只是删除最后一个元素的方法。
...
我们没有提供删除除last之外的任何元素的方法 因为它会引起低效使用,例如O(n ^ 2)过滤循环 应该是O(n)。如果要删除其他元素 比起最后一个,最好的方法是重新安排元素 你要删除的那个是最后一个,然后调用RemoveLast()
...
答案 1 :(得分:10)
Protobuf v2
您可以使用DeleteSubrange(int start, int num)
课程中的RepeatedPtrField
。
因此,如果要删除单个元素,则必须将此方法称为DeleteSubrange(index_to_be_del, 1)
。它将删除该索引处的元素。
Protobuf v3更新
如评论中所述,iterator RepeatedField::erase(const_iterator position)
可以在任意位置删除
答案 2 :(得分:7)
在这些情况下我通常做的是创建一个新的Protobuf(PB)消息。我迭代现有消息的重复字段,并将它们(除了你不想要的那些)添加到新的PB消息中。
答案 3 :(得分:1)
以下是示例:
message GuiChild
{
optional string widgetName = 1;
//..
}
message GuiLayout
{
repeated ChildGuiElement children = 1;
//..
}
typedef google_public::protobuf::RepeatedPtrField<GuiChild> RepeatedField;
typedef google_public::protobuf::Message Msg;
GuiLayout guiLayout;
//Init children as necessary..
GuiChild child;
//Set child fileds..
DeleteElementsFromRepeatedField(*child, guiLayout->mutable_children());
void DeleteElementsFromRepeatedField(const Msg& msg, RepeatedField* repeatedField)
{
for (RepeatedField::iterator it = repeatedField->begin(); it != repeatedField->end(); it++)
{
if (google_public::protobuf::util::MessageDifferencer::Equals(*it, msg))
{
repeatedField->erase(it);
break;
}
}
}