【问题标题】:Swift Node Tree to complex JsonSwift 节点树到复杂的 Json
【发布时间】:2021-07-20 14:02:59
【问题描述】:

我正在开发一个用 swift 编写的工具,它需要将树导出为 json。我一直在遵循描述为 here 的 Swift 树方法作为指南。

我使用以下代码创建一棵树

class Node {
  var value: String
  var children: [Node] = []
  weak var parent: Node?

  init(value: String) {
    self.value = value
  }

  func add(child: Node) {
    children.append(child)
    child.parent = self
  }
}

let beverages = Node(value: "beverages")

let hotBeverages = Node(value: "hot")
let coffee = Node(value: "coffee")

let coldBeverages = Node(value: "cold")
let water = Node(value: "water")
let soda = Node(value: "soda")

beverages.add(child: hotBeverages)
hotBeverages.add(child: coffee)

beverages.add(child: coldBeverages)
coldBeverages.add(child: water)
coldBeverages.add(child: soda)

现在我需要将此代码导出为 json。我将它传递给 webkit,这样我就可以加载 hierarchal tree via D3。这意味着我需要将其导出,使其符合以下格式...

[
 {
  "name": "beverages",
  "children": [
    {
     "name": "cold", 
     "children": [
      {"name": "water"}, 
      {"name": "soda"}
    ]},
    {
      "name": "warm", 
      "children": [
        {"name": "coffee"}
      ]
    }]
  }
]

我看过很多关于将 swift 导出为基本 json 的帖子,但我无法完全理解用这样的树来做这件事。任何帮助将不胜感激!

注意:我不需要漂亮打印的 json。这里只是为了便于阅读

【问题讨论】:

  • 您的 JSON 类数据无效。
  • 没有?它通过javascript加载对我来说很好。如果你想告诉我你想看到什么,很高兴修复它。

标签: json swift macos d3.js


【解决方案1】:

您只需使Node 符合Encodable。您需要做的唯一棘手的步骤是只编码children,以防它有任何元素,否则只编码value。您还需要声明一个符合CodingKeyenum 以告诉Encodable 使用JSON 键name 而不是valuevalue 属性进行编码。

extension Node: Encodable {
    private enum CodingKeys: String, CodingKey {
        case value = "name"
        case children
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(value, forKey: .value)
        if !children.isEmpty {
            try container.encode(children,forKey: .children)
        }
    }
}

然后像这样使用它

do {
    let encodedBevarages = try JSONEncoder().encode(beverages)
    print(String(data: encodedBevarages, encoding: .utf8) ?? "Encoding failed")
} catch {
    error
}

输出:

{"name":"beverages","children":[{"name":"hot","children":[{"name":"coffee"}]},{"name":"cold ","儿童":[{"name":"water"},{"name":"soda"}]}]}

【讨论】:

  • 是的,比我的回答好多了。
  • 效果很好。非常感谢
猜你喜欢
  • 2021-01-18
  • 2021-02-26
  • 2017-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多