我在我的原在重复领域的一些条目。 现在我想删除其中的一些。 我怎样才能做到这一点? 还有就是要删除的最后一个元素的功能,但我想删除任意元素。 我不能只是交换他们,因为顺序很重要。
我可以下一个,直到结束掉,但是是不是有更好的解决方案吗?
我在我的原在重复领域的一些条目。 现在我想删除其中的一些。 我怎样才能做到这一点? 还有就是要删除的最后一个元素的功能,但我想删除任意元素。 我不能只是交换他们,因为顺序很重要。
我可以下一个,直到结束掉,但是是不是有更好的解决方案吗?
根据该API文档 ,没有办法从任意一个重复字段中删除元素,只是一种方法,以消除最后一个。
...
我们不提供一种方法,因为它邀请低效利用,如为O(n ^ 2)滤波回路本来应该为O(n),除去比上次其他任何元素。 如果你想删除除最后的元素,做到这一点的最好办法是重新排列的元素,让你要删除的一个是在年底,然后调用RemoveLast()
...
protobuf的V2
您可以使用DeleteSubrange(int start, int num)
在RepeatedPtrField
类。
所以,如果你想删除一个单一的元素,那么你必须调用此方法DeleteSubrange(index_to_be_del, 1)
这将是指数在删除元素。
protobuf的V3更新
正如在评论中提到的, iterator RepeatedField::erase(const_iterator position)
可以在任意位置删除
我最常做的在这些情况下是创建一个新的Protobuf(PB)消息。 我重复现有信息的重复字段,添加它们(除了那些你不想再)到新的PB信息。
下面是例子:
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;
}
}
}
虽然没有直接的方法,你仍然可以做到这一点(使用反射自定义消息)。 下面的代码删除count
从开始重复域项目row
索引。
void RemoveFromRepeatedField(
const google::protobuf::Reflection *reflection,
const google::protobuf::FieldDescriptor *field,
google::protobuf::Message *message,
int row,
int count)
{
int size = reflection->FieldSize(*message, field);
// shift all remaining elements
for (int i = row; i < size - count; ++i)
reflection->SwapElements(message, field, i, i + count);
// delete elements from reflection
for (int i = 0; i < count; ++i)
reflection->RemoveLast(message, field);
}