Scala: редактировать / изменять строку json на основе внутреннего значения

#json #scala

#json #scala

Вопрос:

У меня есть строка json, структурированная аналогично следующей:

 val json : String =
    {
       "identifier":{
          "id":"1234_567_910",
          "timestamp":"12:34:56",
       },
       "information":[
          {
             "fieldName":"test_name",
             "fieldId":"test_fieldId",
          }
       ]
    }
  

Что я хочу сделать, так это создать проверку, которая проверяет, что поле ‘id’ соответствует структуре «Int_Int_Int», и если это не так, я хочу изменить значение в соответствии с этой предполагаемой структурой, но я хочу сохранить остальную информацию в строке json как есть.

Итак, если бы я получил следующие поля «id» в строке json, я бы хотел изменить их следующим образом:

 "id":"1234_567_910" -> do nothing 
"id":"1234"         -> "id":"1234_0_0"
"id":"1234_567"     -> "id":"1234_567_0"
"id":"1234_???"     -> "id":"1234_0_0"
"id":"1234_??_???"  -> "id":"1234_0_0"
"id":"1234_foo"     -> "id":"1234_0_0"
"id":"1234_567_foo" -> "id":"1234_567_0"
  

Например:

Если я получу json, подобный этому:

 {
   "identifier":{
      "id":"1234",
      "timestamp":"12:34:56",
   },
   "information":[
      {
         "fieldName":"test_name",
         "fieldId":"test_fieldId",
      }
   ]
}
  

Я бы хотел изменить ее, чтобы в итоге получился такой json:

 {
   "identifier":{
      "id":"1234_0_0",
      "timestamp":"12:34:56",
   },
   "information":[
      {
         "fieldName":"test_name",
         "fieldId":"test_fieldId",
      }
   ]
}
  

Какой был бы наиболее эффективный / самый чистый способ добиться такого типа модификации json в Scala?

Комментарии:

1. Сначала выберите библиотеку json. — Во-вторых, решите, хотите ли вы изменить сам json (если выбранная библиотека поддерживает это) или сначала сопоставить его с некоторыми классами case, затем выполните сопоставление в обычном scala и снова сопоставьте классы case с json. — В-третьих, попробуйте реализовать это. — В-четвертых, если у вас возникли какие-либо проблемы, которые вы не смогли решить с помощью Google, откройте новый и более конкретный вопрос.

Ответ №1:

Ниже показано, как это можно сделать с помощью библиотеки Dijon.

 import com.github.pathikrit.dijon._

def normalize(id: String): String =
  id.count(_ == '_') match {
    case 0 => id   "_0_0"
    case 1 => id   "_0"
    case _ => id
  }

val json =
  json"""
    {
       "identifier":{
          "id":"1234",
          "timestamp":"12:34:56"
       },
       "information":[
          {
             "fieldName":"test_name",
             "fieldId":"test_fieldId"
          }
       ]
    }"""
json.identifier.id = json.identifier.id.asString.fold("0_0_0")(normalize)
println(pretty(json))

  

Он должен печатать:

 {
  "identifier": {
    "id": "1234_0_0",
    "timestamp": "12:34:56"
  },
  "information": [
    {
      "fieldName": "test_name",
      "fieldId": "test_fieldId"
    }
  ]
}