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

时间:2014-09-03 12:27:21

标签: protocol-buffers

.proto文件结构

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

message mainMSG
{
  required repetedMSG_id = 1;
  repeated repetedMSG rptMSG = 2;
}

我有一个主要的MSG,其中有太多(假设10个)重复的MSG存在。 现在我想从mainMSG删除任何特定的repetedMSG(假设第5次重复的MSG)。为此我尝试了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;
                    }
                }

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

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

1 个答案:

答案 0 :(得分:3)

您可以使用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;
  }
}

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

// 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);