2015-02-16 3 views
1

Предполагая следующий JSON объект, массив [эпохи, значение] массивов:Как удалить элемент массива в json-c?

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

Что правильный способ, чтобы удалить элемент массива? Идея состоит в том, чтобы удалить тот, у которого ольха эпохи, чем заданное значение. Я использую 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)); 
    } 

Это не удается (SIGSEGV) при вызове json_object_to_json_string() с настроенным объектом.

Спасибо

+0

Не могли бы вы указать, как вы прочитали переменную 'jsonHeatmapObj' из предоставленного JSON? – logc

+0

Обновление вопроса: добавлен вызов json_tokener_parse(). – SCO

ответ

1

Я думаю, что есть две отдельные проблемы, связанные с этим кодом: один является то, что он использует json_object_put, как будто json_object_array_get_idx извлекал элемент он возвращается из исходного массива (то, что не совсем понятно, из API documentation), а во-вторых, он использует 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

+0

Хотя это больше похоже на обходной путь, я соглашусь с этим, так как я думаю, что нет лучшего способа сделать это. Я использовал json_object_array_add() вместо json_object_array_put_idx() для заполнения newHeatMap. – SCO

+0

@SCO: Я отредактировал сообщение, чтобы использовать функцию, которую вы упомянули. Оба дают одинаковый результат. Использование 'json_object_array_put_idx' позволило бы сохранить правильную логику, даже если вы изменили индексный цикл, но, возможно,' json_object_array_add' более интуитивно понятен. Иначе: почему это выглядит как обходной путь? Возвращение нового объекта вместо мутирования не является плохим шаблоном, особенно если задействована потоковая передача. – logc

+0

Из того, что я помню, json_object_array_put_idx() segfaulted. Я пришел к выводу, что json_object_array_put_idx() использовал idx, который был вне границ для newHeatMap. Например, json_object_array_put_idx() 'curJsonHeatpointObj в индексе 2 newHeatMap, где ранее ни один из объектов с индексами 0 или 1 (создание newHeatMap array 0-size) не сделал бы его SIGSEGV. Я всегда ожидаю, что библиотеки разрешат замену на месте (вы правы относительно MT, в этом случае я просто mutex «изменение, когда это приемлемо для этого), потому что код более читабельный, IMHO :). Спасибо ! – SCO

Смежные вопросы