如何组合flatmap所以它只需要使用一次

时间:2018-02-26 02:52:26

标签: 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 let minValOther = data.flatMap({$0.other}).min() else {return}
guard let minVal = data.flatMap({$0.value}).min() else {return}

这个问题是,每次使用flatmap时,它都会循环遍历我的所有数据。有什么更好的方法呢?它全部使用名为data的相同数据集。

2 个答案:

答案 0 :(得分:2)

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

struct Value {
    let percent: Int?
    let profitLoss: Int?
    let price: Int?
    let other: Int?
    let value: Int?
}

您正试图从列表转到单个(元组)值:

var result: (maxPercent: Int?, minProfitLoss: Int?, minPrice: Int?, minOther: Int?, minValue: Int?)

这表明reduce。但在某些情况下,您需要一种方法来Int?使用max和在其他情况下使用min。这表明这样的功能:

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卸载元组。

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

答案 1 :(得分:0)

您可以在以下代码段

中更改代码
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值。