【问题标题】:How to remove an array element in json-c?如何删除json-c中的数组元素?
【发布时间】:2015-04-16 22:23:54
【问题描述】:

假设如下 JSON 对象,一个 [epoch, value] 数组的数组:

[ [0,1], [1912312314,2], [1912312857,5] ]

删除数组元素的正确方法是什么?这个想法是删除一个纪元alder比给定值的那个。我使用 json-c 0.11。

我试过了:

   json_object *jsonHeatmapObj;
   jsonHeatmapObj = json_tokener_parse ( "[ [0,1], [1912312314,2], [1912312857,5] ]" );

    for ( int idx=0 ; idx < json_object_array_length(jsonHeatmapObj) ; idx++ ) {
       json_object *curJsonHeatpointObj = json_object_array_get_idx ( jsonHeatmapObj , idx );
       int x = json_object_get_int ( json_object_array_get_idx ( curJsonHeatpointObj , 0 ) );
       if ( x < time(NULL) - 10 ) {
          json_object_put ( curJsonHeatpointObj );
       }
       printf("\t[%d]=%s\n", idx, json_object_to_json_string(jsonHeatmapObj));
    }

使用调整后的对象调用 json_object_to_json_string() 时失败 (SIGSEGV)。

谢谢

【问题讨论】:

  • 能否请您说明您是如何从提供的 JSON 中读取 jsonHeatmapObj 变量的?
  • 更新了问题:添加了对 json_tokener_parse() 的调用。

标签: arrays json


【解决方案1】:

我认为该代码有两个不同的问题:一个是它使用json_object_put 好像json_object_array_get_idx 已经删除了它从原始数组返回的元素(@987654321 根本不清楚@),其次它使用 time(NULL) 就像它返回一个整数一样,但它返回的是一个 time_t 结构。

第一个可以通过创建一个新的 JSON 数组并仅在满足条件时才包含其中的项目来解决。在这里,我通过使用设置为数组中最大值的时间来避免第二个问题:

struct json_object *newHeatMap = json_object_new_array();
for ( int idx=0 ; idx < json_object_array_length(jsonHeatmapObj) ; idx++ ) {
    json_object *curJsonHeatpointObj = json_object_array_get_idx ( jsonHeatmapObj , idx );
    int x = json_object_get_int ( json_object_array_get_idx ( curJsonHeatpointObj , 0 ) );
    if ( x < 1912312857 ) {
        json_object_array_add(newHeatMap, curJsonHeatpointObj);
    }
    printf("\t[%d]=%s\n", idx, json_object_to_json_string(newHeatMap));
}

我得到以下结果,希望是你想要看到的:

$ gcc -I/opt/local/include -L/opt/local/lib/ -ljson-c main.c && ./a.out example.json
    [0]=[ [ 0, 1 ] ]
    [1]=[ [ 0, 1 ], [ 1912312314, 2 ] ]
    [2]=[ [ 0, 1 ], [ 1912312314, 2 ] ]

第二个问题已经回答了例如here on SO

【讨论】:

  • 虽然这看起来更像是一种解决方法,但我会接受这一点,因为我想没有更好的方法可以做到这一点。我使用 json_object_array_add() 而不是 json_object_array_put_idx() 来填充 newHeatMap。
  • @SCO:我已经编辑了帖子以使用您提到的功能。两者都给出相同的输出。即使您更改了索引循环,使用json_object_array_put_idx 也会保持逻辑正确,但也许json_object_array_add 更直观。否则:为什么这看起来像是一种解决方法?返回一个新对象而不是改变一个对象并不是一个坏模式,特别是在涉及线程的情况下。
  • 据我所知,json_object_array_put_idx() 出现了段错误。我得出的结论是 json_object_array_put_idx() 使用的 idx 超出了 newHeatMap 的范围。例如,在 newHeatMap 的索引 2 处的 json_object_array_put_idx()'ing curJsonHeatpointObj 之前没有添加索引 0 或 1 处的对象(使 newHeatMap 数组大小为 0)将使其成为 SIGSEGV。我总是希望库允许就地替换(关于 MT,您是对的,在这种情况下,我只是在可以接受的情况下互斥更改),因为代码更具可读性,恕我直言 :)。谢谢!
  • @SCO :如果跳过中间元素,您对段错误的看法是正确的。我没有考虑到这一点,现在答案更好了。注意变异状态,它是万恶之源 :)
  • “注意变异状态”,记住这一点! :)
猜你喜欢
  • 2018-10-14
  • 2013-09-01
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
  • 1970-01-01
  • 2022-06-11
  • 2016-09-19
  • 2020-10-21
相关资源
最近更新 更多