代码之家  ›  专栏  ›  技术社区  ›  Guy C

如何为字符串数组配置JSON.mapping使其成为散列?

  •  2
  • Guy C  · 技术社区  · 8 年前

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

    我可以使用以下工具获得基本映射:

    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代码: https://play.crystal-lang.org/#/r/515o

    但理想情况下,我希望价格是一个散列与股票名称作为关键和价格作为价值。这可以通过JSON.mapping实现吗?

    1 回复  |  直到 8 年前
        1
  •  7
  •   Johannes Müller    8 年前

    JSON.mapping 将被移除以支持 JSON::Serializable 和注释。你可以像这样使用它:

    class Midprice
      include JSON::Serializable
    
      getter product : String
    
      @[JSON::Field(converter: StockConverter.new)]
      getter prices : Hash(String, String)
    end
    

    你需要使用 converter 修改 prices

    在这种情况下,输入是 Array(Array(String)) 输出是一个 Hash(String, String) 是另一种类型。您需要实现一个自定义 from_json 转换器的方法。

    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
    

    以下是完整的工作代码: https://play.crystal-lang.org/#/r/51d9