如何过滤数组中特定键的值?

时间:2017-10-25 21:39:19

标签: arrays swift filtering

我们有一个返回数组的json值:

  "sentMoney": [
                {
                    "amount": 3840.83,
                    "currency": "MXN",
                    "isMajor": false
                },
                {
                    "amount": 200,
                    "currency": "USD",
                    "isMajor": true
                }
            ]

我要做的是过滤它,以便我可以获得“金额”键的值。这是我到目前为止,但我得到一个“没有下标成员”错误消息:

 let filteredItem = self.postTransferSuccess?.sentMoney.filter{$0["sentMoney"]}[0]
                    self.emailMessage.amount = filteredItem

感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

由于sentMoney是具有array of dictionary值的密钥,因此您应该这样做:

 let resultObj =  (dict["sentMoney"] as? [[String:Any]])?.filter({ ($0["amount"] as? Double) == someValue }).first // dict should be the name of your dictionary

请记住,您的数据应该如下所示,所以没有大括号:

var dict = ["sentMoney": [
   ["amount": 3840.83,"currency": "MXN", "isMajor": false],
   ["amount": 200.0,"currency": "USD","isMajor": true]
  ]
]

您的第二个选择是将您的词典转换为结构,这将更容易迭代。

struct Item {
    let amount:Double
    let currency:String
    let isMajor:Bool


    init?(_ dict:[String:Any]?) { //<-- failable init will return a nil if there an empty key
    guard let _dict = dict,
    let amount = _dict["amount"] as? Double,
    let currency = _dict["currency"] as? String,
    let isMajor = _dict["isMajor"] as? Bool
        else { return nil }

    self.amount = amount
    self.currency = currency
    self.isMajor = isMajor
   }

}

现在当你需要迭代时,你会做:  var someValue = 200.0

 if let arr = dict["sentMoney"] as? [[String:Any]] {
        let items = arr.flatMap({ Item($0)}) //<-- will remove any optional item from your list
        let singleItem = items.first { $0.amount == someValue } 
     // or arr.flatMap({ Item($0) }).filter({ $0.amount == someValue}).first
  }

(边节点)避免不惜一切代价使用!,如果让let或guard语句打开您的选项,请使用。

答案 1 :(得分:0)

我不完全确定你的问题是什么。 虽然bc .filter用于删除数组/集合中不需要的元素,但.filter不是正确的函数。 (因此,您使用条件进行过滤,只有当该条件的计算结果为true时,它才会将值复制到新集合中。)

您可能正在寻找的是.map

如:

let amountsOnlyArray = sentMoney.map({ $0["amount"] })

会给你[3840.43, 200]

如果您出于某种原因只想要第一项,并且想忽略我 THINK ,那么您应该可以

let firstAmountOnly = sentMoney[0]["amount"]

请注意,amountsOnlyArray实际上属于[Any]类型,因此您必须在某处进行投射。

请注意,假设您拥有某种sentMoney:[String:Any]集合,我假设您已初步代码过滤sentMoney