通过嵌套字典中的键进行快速分组

时间:2018-11-13 06:48:26

标签: swift dictionary filter

我有以下json,我正在尝试使用swift函数将其分组。

{
  "response": [
    {
      "user": "A",
      "details": {
        "source": "Tab"
      }
    },
    {
      "user": "B",
      "details": {
        "source": "Tab"
      }
    },
    {
      "user": "C",
      "details": {
        "source": "Desktop"
      }
    },
    {
      "user": "D",
      "details": {
        "source": "Mobile"
      }
    }
  ]
}

所以我尝试的是通过“详细信息”键进行分组,但是它不允许我在分组方法中添加源密钥。

  

let groupedDict =字典(分组:项,由:{$ 0 [“ device”] as !!   [String:String]})

我唯一可以使用的方法是每次迭代并手动过滤。

我要实现的输出如下:

{
  "Mobile": [
    {
      "user": "C",
      "details": {
        "source": "Mobile"
      }
    }
  ],
  "tab": [
    {
      "user": "A",
      "details": {
        "source": "Tab"
      }
    },
    {
      "user": "B",
      "details": {
        "source": "Tab"
      }
    }
  ],
  "Desktop": [
    {
      "user": "C",
      "details": {
        "source": "Desktop"
      }
    }
  ]
}

任何潜在客户均表示赞赏。 TIA

编辑:

为了能够按特定顺序过滤它。如响应中所示的移动,标签和桌面。

2 个答案:

答案 0 :(得分:4)

我已经实现了,

1-Decode将响应转换为Object

2-过滤了每种类型的3 arrays

3-将这些数组分组。

观察下面的代码。

struct MyObject: Codable {
    var response: [DataBody]
    struct DataBody: Codable {
        var user: String
        var details: Details
    }
    struct Details: Codable {
        var source: String
    }
}

let myObject = try? JSONDecoder().decode(MyObject.self, from: jsonData!)
let tabs = myObject!.response.filter({$0.details.source == "Tab"})
let desktops = myObject!.response.filter({$0.details.source == "Desktop"})
let mobiles =  myObject!.response.filter({$0.details.source == "Mobile"})

var grouped = Dictionary(grouping: myObject!.response, by: { $0.details.source })
[
    "Tab": tabs,
    "Desktop": desktops ,
    "Mobile": mobiles
]
  

这是使用Swift4完成的

我们还没有完成,要100%查看结果

1- encode已分组。

2-将其转换为String

3-打印。

检查一下。

let encdoedData = try!  JSONEncoder().encode(grouped)

let finalResult = String(data: encdoedData, encoding: .utf8)

print(finalResult!)

结果:

  

{“ Tab”:[{“ details”:{“ source”:“ Tab”},“ user”:“ A”},{“ details”:{“ source”:“ Tab”},“ user “:” B“}],”桌面“:[{”详细信息“:{”源“:”桌面“},”用户“:” C“}]],”移动“:[{”详细信息“:{”源”:“移动”},“用户”:“ D”}]}

答案 1 :(得分:1)

遵循三个步骤

  1. 查找“源”键的唯一值
  2. 通过唯一键分组并创建字典
  3. 将字典转换为Json

这里是代码

let response = jsonResult["response"] as! [[String :Any]]

查找“源”键的唯一值

let array = (response).map { ($0["details"] as! [String:Any])["source"] as! String }
let uniqueSourceKeyArray = Set.init(array)

通过唯一键分组并创建字典

var dictTemp = [String:Any]()
for obj in uniqueSourceKeyArray {
let dict = (response).filter({($0["details"] as! [String:Any])["source"] as! String == obj })
  dictTemp[obj] = dict
}

将字典转换为Json

if let jsonResult1 = try JSONSerialization.data(withJSONObject: dictTemp, options: []) as?  Data {
  let finalJson = String.init(data: jsonResult1, encoding: .utf8)
  print(finalJson!)
}

结果

{"Tab":[{"user":"A","details":{"source":"Tab"}},{"user":"B","details":{"source":"Tab"}}],"Mobile":[{"user":"D","details":{"source":"Mobile"}}],"Desktop":[{"user":"C","details":{"source":"Desktop"}}]}