从Google协议缓冲区中删除特定重复字段数据

1 protocol-buffers

.proto 文件结构

消息重复MSG { 所需的字符串数据 = 1; }

message mainMSG
{
  required repetedMSG_id = 1;
  repeated repetedMSG rptMSG = 2;
}
Run Code Online (Sandbox Code Playgroud)

我有一个 mainMSG,其中存在太多(假设 10)个重复的 MSG。现在我想从 mainMSG 中删除任何特定的 repetedMSG (假设第 5 个 repetedMSG )。为此,我尝试了 3 种方法,但没有一种有效。

for (int j = 0; j<mainMSG->repetedMSG_size(); j++){
                    repetedMSG reptMsg = mainMsg->mutable_repetedMSG(j);
                    if (QString::fromStdString(reptMsg->data).compare("deleteMe") == 0){
            *First tried way:-*  reptMsg->Clear();
            *Second tried Way:-* delete reptMsg;
            *Third tried way:-*  reptMsg->clear_formula_name();
                        break;
                    }
                }
Run Code Online (Sandbox Code Playgroud)

当我序列化 mainMSG 以写入文件时,即执行此行时,出现运行时错误

mainMSG.SerializeToOstream (std::fstream output("C:/A/test1", std::ios::out | std::ios::trunc | std::ios::binary)) 这里我得到运行时错误

Ken*_*rda 5

您可以用于RepeatedPtrField::DeleteSubrange()此用途。但是,在循环中使用它时要小心——人们通常编写这样的代码,其时间复杂度为 O(n^2):

// BAD CODE! O(n^2)!
for (int i = 0; i < message.foo_size(); i++) {
  if (should_filter(message.foo(i))) {
    message.mutable_foo()->DeleteSubrange(i, 1);
    --i;
  }
}
Run Code Online (Sandbox Code Playgroud)

相反,如果您打算删除多个元素,请执行以下操作:

// Move all filtered elements to the end of the list.
int keep = 0;  // number to keep
for (int i = 0; i < message.foo_size(); i++) {
  if (should_filter(message.foo(i))) {
    // Skip.
  } else {
    if (keep < i) {
      message.mutable_foo()->SwapElements(i, keep)
    }
    ++keep;
  }
}

// Remove the filtered elements.
message.mutable_foo()->DeleteSubrange(keep, message.foo_size() - keep);
Run Code Online (Sandbox Code Playgroud)