私はprotoの繰り返しフィールドにいくつかのエントリがあります。今私はそれらのいくつかを削除します。どうすればこれを達成できますか?最後の要素を削除する機能がありますが、任意の要素を削除します。順序が重要なので、私はちょうどそれらを交換できません。繰り返しフィールド内の任意のオブジェクトを削除する方法は? (protobuf)
私は次の最後まで交換することができますが、より良い解決策はありませんか?
私はprotoの繰り返しフィールドにいくつかのエントリがあります。今私はそれらのいくつかを削除します。どうすればこれを達成できますか?最後の要素を削除する機能がありますが、任意の要素を削除します。順序が重要なので、私はちょうどそれらを交換できません。繰り返しフィールド内の任意のオブジェクトを削除する方法は? (protobuf)
私は次の最後まで交換することができますが、より良い解決策はありませんか?
API docsによれば、最後のフィールドを削除する方法のように、繰り返しフィールド内から要素を任意に削除する方法はありません。
...
それは非効率的な使用を誘うので、私たちは、このようなOとして、最後の 以外の任意の要素を削除する方法を提供していない(N^2)フィルタリングはO(されている必要があり ループn)。 以外の要素を最後に削除する場合は、削除する要素が最後にあるので、 の要素を並べ替えてから、RemoveLast()を呼び出してください。
...
これらのケースで私が通常行うことは、新しいProtobuf(PB)メッセージを作成することです。私は既存のメッセージの繰り返しフィールドを繰り返し、新しいPBメッセージに追加します。
いるProtobuf v2の
あなたはDeleteSubrange(int start, int num)
RepeatedPtrField
でクラスを使用することができます。要素をstart
インデックスからstart + num - 1
インデックスに削除します。
したがって、1つの要素を削除する場合は、このメソッドをDeleteSubrange(index_to_be_del, 1)
と呼びます。 index_to_be_deleted + 1 - 1 = index_to_be_del
のため、単一の要素が削除されます。これは、@g19fanaticの提案を複製します。
いるProtobuf v3の更新
コメントで述べたように、iterator RepeatedField::erase(const_iterator position)
は、任意の位置で
私は不思議です、なぜ 'erase'を使わないのですか:https:// developers .google.com/protocol-buffers/docs/reference/cpp/google.protobuf.repeated_field#RepeatedField.erase.details – johnbakers
@johnbakersこの時点では、protobuf v3はリリースされていないので、「消去」はv2のプロトタイプではありません。受け入れられた回答には、v2で消去する方法を提供していないことも記載されています。 –
更新された回答 – johnbakers
を削除することができます例です:あなたはまだできなくストレートな方法はありませんが
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;
}
}
}
これを行う(リフレクションを使用するカスタムメッセージの場合)。以下のコードでは、row
インデックスから始まるフィールド項目が繰り返されるcount
が削除されます。
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);
}
私はあまりにも愚かですが、あなたの問題をより詳しく説明できますか?どのフレームワーク/ライブラリで作業していますか?ソースコード? – cxxl
ライブラリはgoogleのプロトコルバッファ(protobuf)です。私はここでソースコードが必要ないと思う。反復フィールドは、STLコンテナと同様のデータ所有者です。 – ManuelSchneid3r
protobuf v3のユーザーの場合は、ここに受け入れられた答えを越えてスクロールしてください。https://stackoverflow.com/a/35837227/10278 – pestophagous