如何删除重复字段中的任意对象? (protobuf的)

时间:2012-11-28 11:21:46

标签: c++ protocol-buffers

我的原型中的重复字段中有一些条目。现在我要删除其中一些。我怎么能做到这一点?有一个删除最后一个元素的函数,但我想删除任意元素。我不能交换它们,因为订单很重要。

我可以与下一个交换直到结束,但是没有更好的解决方案吗?

4 个答案:

答案 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;
        }
    }
}