【问题标题】:Deleting Particular repeated field data from Google protocol buffer从 Google 协议缓冲区中删除特定的重复字段数据
【发布时间】:2014-09-05 07:04:31
【问题描述】:

.proto 文件结构

message repetedMSG { 所需的字符串数据 = 1; }

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

我有一个 mainMSG,其中存在太多(假设 10 个)repetedMSG。 现在我想从 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;
                    }
                }

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

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

【问题讨论】:

    标签: protocol-buffers


    【解决方案1】:

    您可以为此使用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);
    

    【讨论】:

    • 如果我想删除多个元素,我可以使用“iterator erase(const_iterator position)”吗?
    • @Alan 这也是 O(n^2) (就像它在 std::vector 上一样)。
    • 我尝试在 protobuf v2 中使用 DeleteSubrange。但是来自重复字段的元素没有被删除。我试过 for(int var = 0; var DeleteSubrange(var,1); }
    • @ShivaniPahuja 您编写的代码不起作用,因为DeleteSubrange() 更改了所有后续元素的编号,因此var++ 将跳过一个元素。因此,您最终会删除所有其他元素。你需要一个--var,就像我在第一个例子中的--i一样。另外,你的循环是 O(n^2)...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    相关资源
    最近更新 更多