如何删除重复场任意对象? (protobuf的)(How to delete arbitrary

2019-08-03 06:56发布

我在我的原在重复领域的一些条目。 现在我想删除其中的一些。 我怎样才能做到这一点? 还有就是要删除的最后一个元素的功能,但我想删除任意元素。 我不能只是交换他们,因为顺序很重要。

我可以下一个,直到结束掉,但是是不是有更好的解决方案吗?

Answer 1:

根据该API文档 ,没有办法从任意一个重复字段中删除元素,只是一种方法,以消除最后一个。

...
我们不提供一种方法,因为它邀请低效利用,如为O(n ^ 2)滤波回路本来应该为O(n),除去比上次其他任何元素。 如果你想删除除最后的元素,做到这一点的最好办法是重新排列的元素,让你要删除的一个是在年底,然后调用RemoveLast()
...



Answer 2:

protobuf的V2

您可以使用DeleteSubrange(int start, int num)RepeatedPtrField类。

所以,如果你想删除一个单一的元素,那么你必须调用此方法DeleteSubrange(index_to_be_del, 1) 这将是指数在删除元素。

protobuf的V3更新

正如在评论中提到的, iterator RepeatedField::erase(const_iterator position)可以在任意位置删除



Answer 3:

我最常做的在这些情况下是创建一个新的Protobuf(PB)消息。 我重复现有信息的重复字段,添加它们(除了那些你不想再)到新的PB信息。



Answer 4:

下面是例子:

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


Answer 5:

虽然没有直接的方法,你仍然可以做到这一点(使用反射自定义消息)。 下面的代码删除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);
}


文章来源: How to delete arbitrary objects in repeated field? (protobuf)