2014-11-20 10 views
6

मेरे पास पहले से दिखाए गए 1 मान से क्रमबद्ध करने के लिए कोड है, लेकिन मैं सोच रहा हूं कि एकाधिक मानों का उपयोग कैसे क्रमबद्ध करें? मैं सेट द्वारा क्रमबद्ध करना चाहता हूं और फिर कुछ स्ट्रिंग द्वारा क्रमबद्ध करना चाहता हूं।मैं एकाधिक मानों से structs की सरणी कैसे क्रमबद्ध करूं?

एक पूर्णांक है, और इस मामले में एक स्ट्रिंग है। मैंने पूर्णांक को एक स्ट्रिंग में परिवर्तित करने और फिर उन्हें संयोजित करने पर विचार किया था, लेकिन सोचा कि एक बेहतर तरीका होना चाहिए क्योंकि मेरे पास भविष्य में क्रमबद्ध करने के लिए 2 पूर्णांक हो सकते हैं।

struct Condition { 
    var set = 0 
    var someString = "" 
} 

var conditions = [Condition]() 

conditions.append(Condition(set: 1, someString: "string3")) 
conditions.append(Condition(set: 2, someString: "string2")) 
conditions.append(Condition(set: 3, someString: "string7")) 
conditions.append(Condition(set: 1, someString: "string9")) 
conditions.append(Condition(set: 2, someString: "string4")) 
conditions.append(Condition(set: 3, someString: "string0")) 
conditions.append(Condition(set: 1, someString: "string1")) 
conditions.append(Condition(set: 2, someString: "string6")) 

// sort 
let sorted = conditions.sorted { (lhs: Condition, rhs: Condition) -> Bool in 
    return (lhs.set) < (rhs.set) 
} 

// printed sorted conditions 
for index in 0...conditions.count-1 { 
    println("\(sorted[index].set) - \(sorted[index].someString)") 
} 

उत्तर

9

मैं अभी तक स्विफ्ट में प्रवीण नहीं हूँ, लेकिन एक बहु-मापदंड के लिए मूल विचार प्रकार है:

let sorted = conditions.sorted { (lhs: Condition, rhs: Condition) -> Bool in 
    if lhs.set == rhs.set { 
     return lhs.someString < rhs.someString 
    } 
    return (lhs.set) < (rhs.set) 
} 
+0

धन्यवाद @Aaron मेरे कोड को सही करने के लिए। – Cyrille

4

आप someString तुलना set मान एक ही है, अन्यथा, उपयोग होने पर होता अपने मौजूदा तुलना:

let sorted = conditions.sorted { (lhs: Condition, rhs: Condition) -> Bool in 
    if lhs.set == rhs.set { 
     return lhs.someString < rhs.someString 
    } else { 
     return lhs.set < rhs.set 
    } 
} 
+0

यह करता है। धन्यवाद! –

+0

यह काम करता है! धन्यवाद – Led

6

यहां तक ​​कि पिछले जवाब का अनुरोध मामले में बिल्कुल ठीक हैं, हालांकि, मैं एक अधिक सामान्य दृष्टिकोण च शामिल करना चाहते हैं या कि: एक एक place- होने का


struct Foo { 
    var foo: Int 
    var bar: Int 
    var baz: Int 
} 
let foos = [Foo(foo: 1, bar: 2, baz: 3), Foo(foo: 1, bar: 3, baz: 1), Foo(foo: 0, bar: 4, baz: 2), Foo(foo: 2, bar: 0, baz: 0), Foo(foo: 1, bar: 2, baz: 2)] 
let orderedFoos = foos.sortedLexicographically([{ $0.foo <=> $1.foo }, { $0.bar <=> $1.bar }, { $0.baz <=> $1.baz }]) 

तो उस प्रकार के लिए तुलना में इस तरह के प्रकार खुद के लिए स्वाभाविक है बजाय:


infix operator <=> { 
associativity none 
precedence 130 
} 
func <=> &ltT: Comparable>(lhs: T, rhs: T) -> NSComparisonResult { 
    return lhs < rhs ? .OrderedAscending : lhs == rhs ? .OrderedSame : .OrderedDescending 
} 
private func _sortedLexicographically&ltS: SequenceType>(source: S, comparators: [(S.Generator.Element, S.Generator.Element) -> NSComparisonResult]) -> [S.Generator.Element] { 
    return sorted(source, { lhs, rhs in 
     for compare in comparators { 
      switch compare(lhs, rhs) { 
      case .OrderedAscending: return true 
      case .OrderedDescending: return false 
      case .OrderedSame: break 
      } 
     } 
     return false 
    }) 
} 
public func sortedLexicographically&ltS: SequenceType>(source: S, comparators: [(S.Generator.Element, S.Generator.Element) -> NSComparisonResult]) -> [S.Generator.Element] { 
    return _sortedLexicographically(source, comparators) 
} 
extension Array { 
    func sortedLexicographically(comparators: [(Element, Element) -> NSComparisonResult]) -> [Element] { 
     return _sortedLexicographically(self, comparators) 
    } 
} 
यहां से

यह एक आदेश करने के लिए काफी आसान है अनुरोध किया की तरह केवल छँटाई की जरूरत है, आप और अधिक stdlib की तरह दृष्टिकोण का पालन करें और बजाय Comparable का विस्तार कर सकते हैं:


extension Foo: Comparable {} 
func == (lhs: Foo, rhs: Foo) -> Bool { 
    return lhs.foo == rhs.foo && lhs.bar == rhs.bar && lhs.baz == rhs.baz 
} 
func < (lhs: Foo, rhs: Foo) -> Bool { 
    let comparators: [(Foo, Foo) -> NSComparisonResult] = [{ $0.foo <=> $1.foo }, { $0.bar <=> $1.bar }, { $0.baz <=> $1.baz }] 
    for compare in comparators { 
     switch compare(lhs, rhs) { 
     case .OrderedAscending: return true 
     case .OrderedDescending: return false 
     case .OrderedSame: break 
     } 
    } 
    return false 
} 
let comparableOrderedFoos = sorted(foos) 

एक और संभव दृष्टिकोण है जो एकबना रही है वहाँ होगाप्रोटोकॉल जो कहता है कि Comparable फ़ील्ड और किस प्राथमिकता में उनके पास है, लेकिन दुर्भाग्य से मैं इसे वैरिएड जेनरिक का उपयोग किए बिना बनाने के तरीके के बारे में नहीं सोच सकता, जो स्विफ्ट में सामान्य रूप से टाइप की गई सुरक्षा को बनाए रखते हुए स्विफ्ट में 2.0 के रूप में समर्थित नहीं हैं। कोड।

+2

यह सही दृष्टिकोण है, आईएमएचओ। यदि आप एक संरचना को परिभाषित करने जा रहे हैं, और आप इसकी तुलना करने में सक्षम होना चाहते हैं, तो यह संरचना है जो इसे – Abizern

+0

ऑर्डर करने के लिए परिभाषित करती है, वास्तव में, मैं सहमत हूं। लेकिन अभी भी ऐसे मामले हो सकते हैं जहां आप एक वैकल्पिक सॉर्टिंग ऑर्डर दिखाना चाहते हैं और आप इसे संभव बनाना चाहते हैं। जैसा कि वे कहते हैं: वाईएमएमवी – DeFrenZ

+0

स्विफ्ट कस्टम ऑपरेटरों के उपयोग के साथ-साथ इस समस्या को हल करने के लिए जेनरिक टाइप करने के लिए अतिरिक्त अंक दिए जाने चाहिए! वाहवाही! – quickthyme

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