23

プロトの繰り返しフィールドにいくつかのエントリがあります。今、それらのいくつかを削除したいと思います。どうすればこれを達成できますか? 最後の要素を削除する機能がありますが、任意の要素を削除したいです。順序が重要なので、単に交換することはできません。

最後まで next と交換できますが、もっと良い解決策はありませんか?

4

5 に答える 5

17

Protobuf v3 の場合

iterator RepeatedField::erase(const_iterator position)任意の位置で削除できます。

Protobuf v2 の場合

DeleteSubrange(int start, int num)インRepeatedPtrFieldクラスで使えます。

単一の要素を削除する場合は、このメソッドを として呼び出す必要がありますDeleteSubrange(index_to_be_del, 1)。そのインデックスの要素を削除します。

于 2016-03-07T06:07:57.670 に答える
15

APIドキュメントによると、繰り返されるフィールド内から要素を任意に削除する方法はなく、最後の要素を削除する方法があります。

...
O(n)であるはずのO(n ^ 2)フィルタリングループなど、非効率的な使用を招くため、最後の要素以外の要素を削除する方法は提供していません。最後以外の要素を削除する場合は、削除する要素が最後になるように要素を再配置してから、RemoveLast()を呼び出すのが最善の方法
です...

于 2012-12-06T14:39:42.443 に答える
0

次に例を示します。

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;
        }
    }
}
于 2016-03-16T10:31:19.947 に答える
0

簡単な方法はありませんが、これを行うことができます (リフレクションを使用したカスタム メッセージの場合)。以下のコードは、インデックス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);
}
于 2016-08-16T01:20:58.853 に答える