Swift 如何组合flatmap以便只需使用一次

Swift 如何组合flatmap以便只需使用一次,swift,Swift,我有一个类,我需要找到数据集中不同变量的最小值/最大值。现在我是这样做的: guard let maxValPerc = data.flatMap({$0.percent}).max() else {return} guard let minValProf = data.flatMap({$0.profitLoss}).min() else {return} guard let minValPrice = data.flatMap({$0.price}) else {return} guard

我有一个类,我需要找到数据集中不同变量的最小值/最大值。现在我是这样做的:

guard let maxValPerc = data.flatMap({$0.percent}).max() else {return}
guard let minValProf = data.flatMap({$0.profitLoss}).min() else {return}
guard let minValPrice = data.flatMap({$0.price}) else {return}
guard let minValOther = data.flatMap({$0.other}).min() else {return}
guard let minVal = data.flatMap({$0.value}).min() else {return}
func combine(_ x: inout Int?, with: Int?, using: (Int, Int) -> Int) {
    guard let x_ = x else { x = with; return }
    guard let with = with else { return }
    x = using(x_, with)
}

问题是每次我使用flatmap时,它都会在我所有的数据中运行循环。有什么更好的方法可以做到这一点?所有这些数据都是同一个名为
数据的数据集

您可以在下面的代码片段中更改此代码

func separeteDate() {

var percents        : [Int] = []
var profitLosses    : [Int] = []
var prices          : [Int] = []
var others          : [Int] = []
var values          : [Int] = []

for singleData in data {
    if let percent = singleData.percent {
        percents.append(percent)
    }

    if let price = singleData.price {
        prices.append(price)
    }

    if let other = singleData.other {
        others.append(other)
    }

    if let value = singleData.value {
        values.append(value)
    }

    if let profitLoss = singleData.profitLoss {
        profitLosses.append(profitLoss)
    }
}

  guard let maxValPerc = percents.max() else { return }
  guard let minValProf = profitLosses.min() else { return }
  guard let minValPrice = prices.min() else { return }
  guard let minValOther = others.max() else { return }
  guard let minVal = values.min() else { return }

}

您将需要更多的代码,但需要更少的循环。对于本例,我认为您的结构只有Int值。

不太清楚您的数据类型是什么,但我假设它是这样的(因为您使用的是
flatMap
):

您正在尝试从列表转换为单个(元组)值:

这建议
减少
。但在某些情况下,您需要使用
max
min
组合
Int?
。这表明了这样一个功能:

guard let maxValPerc = data.flatMap({$0.percent}).max() else {return}
guard let minValProf = data.flatMap({$0.profitLoss}).min() else {return}
guard let minValPrice = data.flatMap({$0.price}) else {return}
guard let minValOther = data.flatMap({$0.other}).min() else {return}
guard let minVal = data.flatMap({$0.value}).min() else {return}
func combine(_ x: inout Int?, with: Int?, using: (Int, Int) -> Int) {
    guard let x_ = x else { x = with; return }
    guard let with = with else { return }
    x = using(x_, with)
}
然后将其与
reduce
放在一起:

data.reduce(into: result) { (acc, value) in
    combine(&acc.maxPercent, with: value.percent, using: max)
    combine(&acc.minProfitLoss, with: value.profitLoss, using: min)
    combine(&acc.minPrice, with: value.price, using: min)
    combine(&acc.minOther, with: value.other, using: min)
    combine(&acc.minValue, with: value.value, using: min)
}
如果愿意,可以卸载
保护
的元组

guard let maxPercent = result.maxPercent,
    let minProfitLoss = result.minProfitLoss,
    let minPrice = result.minPrice,
    let minOther = result.minOther,
    let minValue = result.minValue
    else { return }

请注意,OP使用flatMap可能是因为他类中的所有属性都是optionals(Double),也可能是因为它可以是数组的数组。flatMap不只是因为有选项才被使用。但是你说的完全有道理,注意max/min方法也会迭代每个数组的所有元素