2015-10-27 27 views
9

अंतिम कथन त्रुटि के साथ संकलन करने में विफल क्यों होता है: Binary operator '==' cannot be applied to two '[[Simple]]’ operands, और Simple संरचना को संशोधित करने या == ऑपरेटर को संशोधित करने का एक तरीका है, ताकि नेस्टेड सरणी पर समानता जांच करने में सक्षम हो सके (या शब्दकोश)?घोंसला वाले सरणी पर स्विफ्ट समानता ऑपरेटर

var i1: [Int] = [1] 
var i2: [Int] = [1] 
i1 == i2 // -> true 


var i3: [[Int]] = [[1], [2]] 
var i4: [[Int]] = [[1], [2]] 
i3 == i4 // -> true 


struct Simple: Equatable, Hashable { 
    let message: String 

    var hashValue: Int { 
     return message.hashValue 
    } 
} 
func ==(lhs: Simple, rhs: Simple) -> Bool { 
    return lhs.message == rhs.message 
} 

var a: [Simple] = [Simple(message: "a")] 
var b: [Simple] = [Simple(message: "a")] 
a == b // -> true 

var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] 
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] 
x == y // -> ERROR! Binary operator '==' cannot be applied to two '[[Simple]]’ operands 

उत्तर

14

कारण Why is Equatable not defined for optional arrays में के रूप में समान है। सरणी तुलना में किया जा सकता है == साथ अगर तत्व प्रकार Equatable है:

/// Returns true if these arrays contain the same elements. 
public func ==<Element : Equatable>(lhs: [Element], rhs: [Element]) -> Bool 

है यही कारण है कि

var a: [Simple] = [Simple(message: "a")] 
var b: [Simple] = [Simple(message: "a")] 
a == b // -> true 

संकलित करता है।

लेकिन फिर भी equatable प्रकार T के लिए, Array<T>Equatable प्रोटोकॉल के अनुरूप नहीं है, Why can't I make Array conform to Equatable? की तुलना करें। इसलिए,

var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] 
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] 
x == y // -> ERROR! Binary operator '==' cannot be applied to two '[[Simple]]’ operands 

x और y में तत्व प्रकार [Simple] जो करता Equatable प्रोटोकॉल के अनुरूप नहीं साथ सरणियों कर रहे हैं, और वहाँ कोई == ऑपरेटर मिलान है।

आप के रूप

func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool { 
    return lhs.count == rhs.count && !zip(lhs, rhs).contains {$0 != $1 } 
} 

या अधिक बस (के रूप में @kennytm ने सुझाव दिया) बस नेस्ट सरणियों के लिए एक सामान्य == ऑपरेटर निर्धारित कर सकते हैं:

func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool { 
    return lhs.elementsEqual(rhs, by: ==) 
} 

यह x == y संकलन और काम करता है के रूप में उम्मीद। वर्तमान में, लगता है कि मनमाने ढंग से नेस्टेड सरणी पर == ऑपरेटर को परिभाषित करने का कोई तरीका नहीं है।

नोट्स:

  • स्विफ्ट 4.1 (वर्तमान में विकास में, snapshots available) के रूप में:

    The standard library types Optional, Array, and Dictionary now conform to the Equatable protocol when their element types conform to Equatable. ...

    (स्विफ्ट CHANGELOG से)। यह उपरोक्त कामकाज अप्रचलित बनाता है।

  • सामान्य सशर्त अनुरूपता, जैसा कि SE-0143 Conditional conformances, में प्रस्तावित किया गया है अभी तक लागू नहीं किया गया है।

+0

शायद 'lhs.elementsEqual (rhs, by: ==)' के कार्यान्वयन को अपडेट करें? – kennytm

+0

@kennytm: अच्छा सुझाव, धन्यवाद! –

+0

सुझाव: चूंकि https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md स्विफ्ट 4 में शामिल नहीं किया गया था, उत्तर –

1

आपको निम्न रूप इसके लिए एक == समारोह को लागू करने, द्वारा यह कर सकते हैं:

func == (lhs: [[Simple]], rhs: [[Simple]]) -> Bool { 
    //your code 
} 
+0

नीचे वोट के लिए खेद है, लेकिन यह प्रश्न आपके उत्तर का तात्पर्य से कहीं अधिक जटिल है। – Jeff

+0

@ जेफ आप अपनी राय के हकदार हैं लेकिन मैं हमेशा जटिल लोगों पर सरल समाधान पसंद करता हूं। [यागनी] (https://en.wikipedia.org/wiki/You_aren't_gonna_need_it) यहां लागू होता है। – Adam

+0

मेरी टिप्पणी एक अनावश्यक जटिल जवाब पसंद करने के बारे में नहीं था। आपका उत्तर इस प्रश्न का समाधान नहीं है। आपका जवाब अधूरा है। सवाल समझने की तुलना में सवाल अधिक जटिल है। – Jeff

संबंधित मुद्दे