2017-04-10 73 views
-1

我將Swift代碼從Xcode 8.3.1降級到Xcode 7.3.1。swift on array.sort - 表達式太複雜,無法在合理的時間內解決;考慮將表達式拆分爲不同的子表達式

Xcode 7.3.1的Swift編譯器提高了 Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions 指向線zeroParameterAndPaths.sort {。代碼在Xcode 8.3.1中是可以的。

怎麼了,怎麼解決?

class NewConnectingSegmentZeroParameterAndPath { 
    let step : Int; // 0 = main, 1 = first outline, 2 = second outline 
    let parameter : CGFloat; 

    init(step: Int, parameter: CGFloat) { 
     self.step = step; 
     self.parameter = parameter; 
    } 
} 



var zeroParameterAndPaths : [NewConnectingSegmentZeroParameterAndPath] = []; 

// ... some zeroParameterAndPaths .appendContentsOf calls 

zeroParameterAndPaths.sort { 
      return $0.parameter < $1.parameter 
        || ($0.parameter == $1.parameter 
        && ($0.step == 1 || ($0.step == 0 && $1.step == 2)) 
      ) 
     }; 
+0

仍抱怨。 – alik

+2

對於我而言,並不完全清楚你想要的排序順序是什麼,但是(除非我錯了),閉包返回'true',用於'* ='的*相同*參數。這是不允許的。 - (與你當前的問題無關,但我只想提及它) –

+0

@MartinR編譯器問題不是人們應該避免這樣的表達式的原因xD – Alexander

回答

1

您有兩種選擇。一種是簡單地做錯誤信息顯示什麼,即拉動複雜的布爾分裂成獨立的部分:

zeroParameterAndPaths.sort { 
     let bless = ($0.parameter < $1.parameter) 
     let beq = ($0.parameter == $1.parameter) 
     let band = ($0.step == 0 && $1.step == 2) 
     let bor = ($0.step == 1 || band) 
     let beqandbor = (beq && bor) 
     return (bless || beqandbor) 
    }; 

另一種是提供一個明確的in線給帕拉姆類型和結果類型:

zeroParameterAndPaths.sort { 
     (a:NewConnectingSegmentZeroParameterAndPath, b:NewConnectingSegmentZeroParameterAndPath) -> Bool in 
     return a.parameter < b.parameter 
      || (a.parameter == b.parameter 
       && (a.step == 1 || (a.step == 0 && b.step == 2)) 
     ) 
    }; 
+0

另外,你是不是指'sortInPlace'? – matt

+0

在Swift 2中排序在Swift 3〜sortInPlace中,所以在技術上是的。但我選擇的第二種方法不適用於sortInPlace(不記得錯誤),所以我在開頭添加了「zero ... =」。 – alik

0

除了類型推理引擎無法快速解決這樣複雜的bool表達式的問題之外,這些表達式實際上很難遵循。我建議你把它分解成簡單的東西,像這樣:

zeroParameterAndPaths.sort { 
    if $0.parameter != $1.parameter { return $0.parameter < $1.parameter ] 
    if $0.step == 1 { return true } 
    if $0.step == 0 && $1.step == 2 { return true } 
    return false 
}; 

這是我的嘗試。我甚至不確定這是否正確,原始表達式很難遵循。

1

你也可以讓你的班級更有幫助,並使其實施條件。編譯器在函數體中比在關閉中困惑的可能性要小得多:

class NewConnectingSegmentZeroParameterAndPath { 
    let step : Int; // 0 = main, 1 = first outline, 2 = second outline 
    let parameter : CGFloat; 

    init(step: Int, parameter: CGFloat) { 
     self.step = step; 
     self.parameter = parameter; 
    } 

    func orderedBefore(_ other: NewConnectingSegmentZeroParameterAndPath) -> Bool 
    { 
     return parameter < other.parameter 
      || parameter == other.parameter 
       && (step == 1 || step == 0 && other.step == 2) 
    } 
} 



var zeroParameterAndPaths : [NewConnectingSegmentZeroParameterAndPath] = []; 

// ... some zeroParameterAndPaths .appendContentsOf calls 

zeroParameterAndPaths.sort { $0.orderedBefore($1) } 
相關問題