Сохранить экземпляр класса как JSON - PullRequest
0 голосов
/ 31 декабря 2018

Проблема

Я работаю над проектом с различными классами, разработанными на заказ.Я хотел бы сохранить некоторые экземпляры классов в конце моей программы, чтобы экспортировать их в базу данных.Я попытался использовать jsonlite::toJSON(account), но получил сообщение об ошибке

Ошибка: нет метода для класса S4: BankAccount

Класс

У меня есть следующий класс

BankAccount <- setRefClass('BankAccount', 
                       fields  = list(
                         balance = 'numeric',
                         ledger = 'data.frame'
                         ),
                       methods = list(
                         deposit  = function (x) {
                           x <- max(x,0)
                           balance <<- balance + x
                           ledger <<- data.frame(
                             Date   = c(ledger$Date, as.character(Sys.time())),
                             Type   = c(ledger$Type, 'Deposit'),
                             Amount = c(ledger$Amount, x),
                             stringsAsFactors = FALSE
                           )
                          },
                         withdraw = function (x) {
                           x <- max(x,0)
                           balance <<- balance - x
                           ledger <<- data.frame(
                             Date   = c(ledger$Date, as.character(Sys.time())),
                             Type   = c(ledger$Type, 'Withdrawal'),
                             Amount = c(ledger$Amount, x),
                             stringsAsFactors = FALSE
                           )
                         }
                       ))

Экземпляр

А вот экземпляр этого класса

account <- BankAccount$new(balance = 100)
account$deposit(1000)
Sys.sleep(5)
account$withdraw(97.89)
account
Reference class object of class "BankAccount"
Field "balance":
[1] 1002.11
Field "ledger":
                 Date       Type  Amount
1 2018-12-31 16:21:20    Deposit 1000.00
2 2018-12-31 16:21:26 Withdrawal   97.89

JSON

Теперь я хотел бы сохранить его в виде файла JSON формы (в JSON может быть опечатка - не очень знаком с форматом)

{
  "balance": "double",
  "ledger": {
    "Date": "string",
    "Type": "string",
    "Amount": "double"
  }
}

PS

Я также пытался без поля ledger (который относится к классу data.frame), но он все еще не работал.


Редактировать

Вот вывод jsonlite::serializeJSON(account)

{"type":"S4","attributes":{".xData":{"type":"environment","attributes":{},"value":{}}},"value":{"class":"BankAccount","package":".GlobalEnv"}} 

Как вы можете видеть, он сохраняет только информацию о классе BankAccount, но не оэкземпляр account (значение баланса и т. д. отсутствует).

1 Ответ

0 голосов
/ 31 декабря 2018

Вот обходной путь (как указано @StefanF).Можно добавить методы к классам

# converts to JSON
toJSON = function (prettifyy = TRUE) {
           instanceJSON <- jsonlite::toJSON(list(balance = balance,ledger  = ledger))
           if (prettifyy) instanceJSON <- jsonlite::prettify(instanceJSON)
           instanceJSON
         }
# saves as .json, e.g. path = 'C:/Test/instance.json'
saveJSON = function (path) {
             instanceJSON <- toJSON()
             writeLines(instanceJSON, path)
           }

Решение не идеальное, так как

  • есть немного труда, так как нужно указать, какие из полей должны быть включены
  • также, если поле BankAccount относится к классу MyClass (другой пользовательский класс), то вам нужно либо указать, какие поля MyClass являются релевантными, либо создать toJSON также для MyClass
...