【问题标题】:How can I remove all JSON objects that have a certain key/value pair from an array of JSON objects?如何从 JSON 对象数组中删除具有特定键/值对的所有 JSON 对象?
【发布时间】:2020-06-13 03:18:07
【问题描述】:

我想像这样过滤数据集:

例如这里是一些假数据集:

[
    {
      "name": "Sakura",
      "hasChildren": false,
      "livesInCity": true,
      "pets": [
          { 
              "cats": ["Luna", "Milk"],
              "type": "tabby"
          }
       ]
    },
    {
      "name": "Linn",
      "hasChildren": false,
      "livesInCity": true,
      "pets": [
          { 
              "cats": ["Luna"],
              "type": "tabby"
          }
       ]
    },
    {
      "name": "Donna",
      "hasChildren": false,
      "livesInCity": false,
      "pets": [
          { 
              "cats": ["Luna", "Milk"],
              "type": "tabby"
          }
       ]
    },
    {
      "name": "Tia",
      "hasChildren": false,
      "livesInCity": false,
      "pets": [
          { 
              "cats": ["Luna", "Milk"],
              "type": "tuxedo"
          }
       ]
    },
    {
      "name": "Dora",
      "hasChildren": false,
      "livesInCity": true,
      "pets": [
          { 
              "cats": ["Artemis", "Milk"],
              "type": "tuxedo"
          }
       ]
    }
]

我想过滤掉所有有"livesInCity": false:

[
    {
      "name": "Sakura",
      "hasChildren": false,
      "livesInCity": true,
      "pets": [
          { 
              "cats": ["Luna", "Milk"],
              "type": "tabby"
          }
       ]
    },
    {
      "name": "Linn",
      "hasChildren": false,
      "livesInCity": true,
      "pets": [
          { 
              "cats": ["Luna"],
              "type": "tabby"
          }
       ]
    },
    {
      "name": "Dora",
      "hasChildren": false,
      "livesInCity": true,
      "pets": [
          { 
              "cats": ["Artemis", "Milk"],
              "type": "tuxedo"
          }
       ]
    }
]

我该怎么做?这可能吗?

在python中我相信是这样的,但我不知道如何开始使用Swift:

people = [person for person in people if person.livesInCity == True]

另外,我怎样才能过滤上面的这个数据集看起来像这样 - 我想按名称分类。

{
    "tabby": ["Sakura", "Linn"],
    "tuxedo": ["Dora"],
}

任何帮助将不胜感激!

【问题讨论】:

  • Swift 不能直接使用 JSON。您首先将 JSON 转换为 Swift 对象 - 在这种情况下,这将是一个对象数组,然后您可以在数组上使用 .filter 函数,并使用您需要的任何逻辑。

标签: arrays json swift


【解决方案1】:

正如 cmets 中已经提到的,您不能直接在 Swift 中处理 JSON 对象。他们需要先转换。

您可以将 JSON 解析为 Swift 对象,然后执行过滤、分组等操作。

struct Person: Codable {
    let name: String
    let hasChildren: Bool
    let livesInCity: Bool
    let pets: [Pet]
}

struct Pet: Codable {
    let cats: [String]
    let type: String
}
let jsonStr = "[{"name": "Sakura", ..." // your JSON string
let jsonData = jsonStr.data(using: .utf8)!
let parsedObjects = try! JSONDecoder().decode([Person].self, from: data)

然后你可以过滤你的 parsedObjects:

let filteredObjects = parsedObjects.filter({ person in person.livesInCity == true })

或更短的(swiftier)版本:

let filteredObjects = parsedObjects.filter { $0.livesInCity }

您也可以尝试按宠物类型分组:

var groupedDict = [String:[String]]()
filteredObjects.forEach{ person in
    person.pets.forEach { pet in
        if let _ = groupedDict[pet.type] {
            groupedDict[pet.type]!.append(person.name)
        } else {
            groupedDict[pet.type] = [person.name]
        }
    }
}
print(groupedDict)
//prints ["tabby": ["Sakura", "Linn"], "tuxedo": ["Dora"]]

如果您想在任何时候将对象转换回 JSON,您可以使用:

let dictData = try! JSONEncoder().encode(groupedDict)
let dictStr = String(data: dictData, encoding: .utf8)!
print(dictStr)
//prints {"tabby":["Sakura","Linn"],"tuxedo":["Dora"]}

注意

为了简单起见,我在解码/编码对象时使用了强制可选展开 (!)。您可能想改用 do-try-catch(捕获错误)。

【讨论】:

  • 不仅 Swift 不能修改 JSON 对象,而且有人试图使用任何类型的工具直接修改 JSON 对象的想法让我毛骨悚然。 JSON 是一种用于传输的格式,也可能用于存储,它不是您应该尝试编辑的格式。
猜你喜欢
  • 2018-09-26
  • 2020-08-28
  • 1970-01-01
  • 2019-06-13
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 2014-09-06
  • 1970-01-01
相关资源
最近更新 更多