How to configure JSON.mapping for Array of Array of Strings to become a Hash?

。_饼干妹妹 提交于 2019-12-07 16:55:52

问题


I am trying to process the following JSON that I receive from an API.

{"product":"midprice",
"prices":[
  ["APPLE","217.88"],
  ["GOOGLE","1156.05"],
  ["FACEBOOK","160.58"]
]}

I can get a basic mapping working with:

require "json"

message = "{\"product\":\"midprice\",\"prices\":[[\"APPLE\",\"217.88\"],[\"GOOGLE\",\"1156.05\"],[\"FACEBOOK\",\"160.58\"]]}"

class Midprice
  JSON.mapping(
    product: String,
    prices: Array(Array(String)),
  )
end

midprice = Midprice.from_json(message)
p midprice.product # Outputs the String
p midprice.prices # Outputs 

Crystal 0.26.1 Code: https://play.crystal-lang.org/#/r/515o

But ideally I would like prices to be a hash with the stock name as the key and the price as the value. Can this be done with JSON.mapping?


回答1:


JSON.mapping is going to be removed in favor of JSON::Serializable and annotations. You can use it like:

class Midprice
  include JSON::Serializable

  getter product : String

  @[JSON::Field(converter: StockConverter.new)]
  getter prices : Hash(String, String)
end

You need to use a converter to modify prices into the format that you want.

In this case the input is an Array(Array(String)) and the output is a Hash(String, String) which is a different type. You need to implement a custom from_json method for your converter.

class StockConverter
  def initialize
    @prices = Hash(String, String).new
  end

  def from_json(pull : JSON::PullParser)
    pull.read_array do
      pull.read_array do
        stock = pull.read_string
        price = pull.read_string

        @prices[stock] = price
      end
    end

    @prices
  end
end

Here's the full working code: https://play.crystal-lang.org/#/r/51d9



来源:https://stackoverflow.com/questions/52377857/how-to-configure-json-mapping-for-array-of-array-of-strings-to-become-a-hash

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!