प्रॉपर्टी वैल्यू द्वारा कस्टम ऑब्जेक्ट्स की सरणी को कैसे स्विफ्ट करें


520

हम कहते हैं कि हमारे पास एक कस्टम वर्ग है जिसका नाम इमेजफाइल है और इस वर्ग में दो गुण हैं।

class imageFile  {
    var fileName = String()
    var fileID = Int()
}

उनमें से बहुत सारे ऐरे में संग्रहीत हैं

var images : Array = []

var aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 101
images.append(aImage)

aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 202
images.append(aImage)

सवाल यह है: मैं कैसे 'fileID' ASC या DESC द्वारा छवियों की सरणी को सॉर्ट कर सकता हूं?


जवाबों:


940

सबसे पहले, अपने ऐरे को एक टाइप किए गए ऐरे के रूप में घोषित करें, ताकि आप जब आप इसे टाइप कर सकें तो आप कॉल कर सकें:

var images : [imageFile] = []

तो आप बस कर सकते हैं:

स्विफ्ट 2

images.sorted({ $0.fileID > $1.fileID })

स्विफ्ट 3+

images.sorted(by: { $0.fileID > $1.fileID })

ऊपर दिया गया उदाहरण desc सॉर्ट ऑर्डर देता है


1
मुझे ऐरे डिक्लेरेशन पार्ट याद आ रहा था, इसने ट्रिक ऐरे <imageFile> किया।
मौह

1
@AlexWayne मेरे पास एक NSManagedObjectउपवर्ग है, जिसे CheckInAndOut कहा जाता है । और एक अलग फाइल में, मैंने इस प्रकार की वस्तुओं के लिए एक टाइप की गई सरणी घोषित की है और जब मैं इसे सॉर्ट करने की कोशिश करता हूं, तो मुझे कोई त्रुटि नहीं मिल सकती है। किसी भी विचार यह क्यों है?
इसरू

3
मुझे मेरी समस्या का पता चला। जाहिर है कि सरणी टाइप की गई सरणी नहीं थी। वैसे भी मेरे पास एक नया मुद्दा है। मैं एक गुण को एक से अधिक गुणों से कैसे क्रमित कर सकता हूं? कहते हैं कि मैं 2 गुण की तरह है firstNameऔर lastNameकी एक सरणी में Personवस्तुओं। पहले मैं इसके द्वारा छाँटना चाहता हूँ firstNameऔर फिर lastName। मैं यह कैसे कर सकता हूं?
Isuru

12
क्या अब आपको करने की आवश्यकता है images.sortInPlace({ $0.fileID > $1.fileID })?
टेलर एम

13
अगर कोई भी ऐसा ही सोच रहा है: जवाब डेसी ऑर्डर देगा
डैनी वांग

223

[ स्विफ्ट 3 के लिए अद्यतित क्रमबद्ध रूप से (:) द्वारा) यह, एक अनुगामी बंद का शोषण करता है:

images.sorted { $0.fileID < $1.fileID }

जहां आप क्रमशः ASC या DESC के आधार पर उपयोग <या >निर्भर करते हैं। यदि आप imagesसरणी को संशोधित करना चाहते हैं , तो निम्नलिखित का उपयोग करें:

images.sort { $0.fileID < $1.fileID }

यदि आप इसे बार-बार करने जा रहे हैं और किसी फ़ंक्शन को परिभाषित करना पसंद करते हैं, तो एक तरीका यह है:

func sorterForFileIDASC(this:imageFile, that:imageFile) -> Bool {
  return this.fileID > that.fileID
}

और फिर निम्नानुसार उपयोग करें:

images.sort(by: sorterForFileIDASC)

मैं इसे स्ट्रिंग के साथ कैसे मुकदमा कर सकता हूं? मुझे इसकी लंबाई के आधार पर स्ट्रिंग को क्रमबद्ध करने की आवश्यकता है
मुनीफ एम

@MeeeefM सिर्फ string1.length <string2.length
सुरजीत राजपूत

sortXcode 8 में इस सिंटैक्स के साथ अब कोई संकलन नहीं है। Xcode 8 कहता है कि $0.fileID < $1.fileIDएक Bool नहीं ComparisonResult का उत्पादन करता है।
क्रैशहाल

3
इस उत्तर का कोड Xcode8 में ठीक काम करता है; यदि आपको कोई त्रुटि मिली है, तो एक नया प्रश्न पोस्ट करें।
गोजोनर

क्या मैं इसकी तुलना तुलना के आधार पर करने के लिए भी कर सकता हूं, उदाहरण के लिए सप्ताह के दिनों तक सरणी क्रमबद्ध होना? यदि हां, तो कैसे?
क्रिस्टोफर

53

लगभग हर कोई देता है कि कैसे सीधे, मुझे विकास दिखाने के लिए:

आप ऐरे के उदाहरण तरीकों का उपयोग कर सकते हैं:

// general form of closure
images.sortInPlace({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })

// types of closure's parameters and return value can be inferred by Swift, so they are omitted along with the return arrow (->)
images.sortInPlace({ image1, image2 in return image1.fileID > image2.fileID })

// Single-expression closures can implicitly return the result of their single expression by omitting the "return" keyword
images.sortInPlace({ image1, image2 in image1.fileID > image2.fileID })

// closure's argument list along with "in" keyword can be omitted, $0, $1, $2, and so on are used to refer the closure's first, second, third arguments and so on
images.sortInPlace({ $0.fileID > $1.fileID })

// the simplification of the closure is the same
images = images.sort({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })
images = images.sort({ image1, image2 in return image1.fileID > image2.fileID })
images = images.sort({ image1, image2 in image1.fileID > image2.fileID })
images = images.sort({ $0.fileID > $1.fileID })

सॉर्ट के कार्य सिद्धांत के बारे में विस्तृत विवरण के लिए, सॉर्ट किए गए फ़ंक्शन को देखें


क्या मैं इसकी तुलना तुलना के आधार पर करने के लिए भी कर सकता हूं, उदाहरण के लिए सप्ताह के दिनों तक सरणी क्रमबद्ध होना? यदि हां, तो कैसे?
क्रिस्टोफर

एक उत्तर पोस्ट करने के लिए धन्यवाद, जो दिखाता है कि पाठकों को "सरलीकृत" बंद करने की गूढ़ वाक्य रचना को समझने के बजाय एक करीबी कैसे काम करता है!
user1118321

50

स्विफ्ट 3

people = people.sorted(by: { $0.email > $1.email })

मैं एक तारीख की तुलना के साथ यह कोशिश की है, यह काम नहीं कर सका। कोई उपाय?
Ebru Güngör

NSDate या स्ट्रिंग नहीं, वर्तमान स्विफ्ट 3 दिनांक ऑब्जेक्ट।
Ebru Güngör

आप किस दिनांक की संपत्ति की तुलना कर रहे हैं? संपत्ति का उपयोग किए गए फ़ंक्शन के साथ तुलना करने में सक्षम होना चाहिए (मेरे उदाहरण से अधिक)
quemeful

9
यह 2017 के लिए एकमात्र उपयोगी उत्तर है।
फेटी

@ फटी का क्या मतलब है? सही वाक्य विन्यास हैpeople.sort { $0.email > $1.email }
लियो डबस

43

स्विफ्ट 5 के साथ, Arrayदो तरीके हैं जिन्हें बुलाया गया है sorted()और sorted(by:)। पहली विधि, sorted()निम्नलिखित घोषणा है:

संग्रह के तत्वों को वापस लौटाता है।

func sorted() -> [Element]

दूसरी विधि, sorted(by:)में निम्नलिखित घोषणा है:

संग्रह के तत्वों को देता है, तत्वों के बीच तुलना के रूप में दिए गए विधेय का उपयोग करके सॉर्ट किया जाता है।

func sorted(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> [Element]

# 1। तुलनीय वस्तुओं के लिए आरोही क्रम के साथ क्रमबद्ध करें

यदि आपके संग्रह के अंदर मौजूद तत्व प्रकार Comparableप्रोटोकॉल के अनुरूप है , तो आप sorted()अपने तत्वों को आरोही क्रम से क्रमबद्ध करने के लिए उपयोग कर पाएंगे । निम्नलिखित खेल का मैदान कोड दिखाता है कि कैसे उपयोग किया जाए sorted():

class ImageFile: CustomStringConvertible, Comparable {

    let fileName: String
    let fileID: Int
    var description: String { return "ImageFile with ID: \(fileID)" }

    init(fileName: String, fileID: Int) {
        self.fileName = fileName
        self.fileID = fileID
    }

    static func ==(lhs: ImageFile, rhs: ImageFile) -> Bool {
        return lhs.fileID == rhs.fileID
    }

    static func <(lhs: ImageFile, rhs: ImageFile) -> Bool {
        return lhs.fileID < rhs.fileID
    }

}

let images = [
    ImageFile(fileName: "Car", fileID: 300),
    ImageFile(fileName: "Boat", fileID: 100),
    ImageFile(fileName: "Plane", fileID: 200)
]

let sortedImages = images.sorted()
print(sortedImages)

/*
 prints: [ImageFile with ID: 100, ImageFile with ID: 200, ImageFile with ID: 300]
 */

# 2। तुलनीय वस्तुओं के लिए अवरोही क्रम के साथ क्रमबद्ध करें

यदि आपके संग्रह के अंदर मौजूद तत्व प्रकार Comparableप्रोटोकॉल के अनुरूप है , तो आपको sorted(by:)अपने तत्वों को अवरोही क्रम से क्रमबद्ध करने के लिए उपयोग करना होगा ।

class ImageFile: CustomStringConvertible, Comparable {

    let fileName: String
    let fileID: Int
    var description: String { return "ImageFile with ID: \(fileID)" }

    init(fileName: String, fileID: Int) {
        self.fileName = fileName
        self.fileID = fileID
    }

    static func ==(lhs: ImageFile, rhs: ImageFile) -> Bool {
        return lhs.fileID == rhs.fileID
    }

    static func <(lhs: ImageFile, rhs: ImageFile) -> Bool {
        return lhs.fileID < rhs.fileID
    }

}

let images = [
    ImageFile(fileName: "Car", fileID: 300),
    ImageFile(fileName: "Boat", fileID: 100),
    ImageFile(fileName: "Plane", fileID: 200)
]

let sortedImages = images.sorted(by: { (img0: ImageFile, img1: ImageFile) -> Bool in
    return img0 > img1
})
//let sortedImages = images.sorted(by: >) // also works
//let sortedImages = images.sorted { $0 > $1 } // also works
print(sortedImages)

/*
 prints: [ImageFile with ID: 300, ImageFile with ID: 200, ImageFile with ID: 100]
 */

# 3। गैर-तुलनीय वस्तुओं के लिए आरोही या अवरोही क्रम के साथ क्रमबद्ध करें

यदि आपके संग्रह के अंदर मौजूद तत्व प्रकार Comparableप्रोटोकॉल के अनुरूप नहीं है, तो आपको sorted(by:)अपने तत्वों को आरोही या अवरोही क्रम से क्रमबद्ध करने के लिए उपयोग करना होगा ।

class ImageFile: CustomStringConvertible {

    let fileName: String
    let fileID: Int
    var description: String { return "ImageFile with ID: \(fileID)" }

    init(fileName: String, fileID: Int) {
        self.fileName = fileName
        self.fileID = fileID
    }

}

let images = [
    ImageFile(fileName: "Car", fileID: 300),
    ImageFile(fileName: "Boat", fileID: 100),
    ImageFile(fileName: "Plane", fileID: 200)
]

let sortedImages = images.sorted(by: { (img0: ImageFile, img1: ImageFile) -> Bool in
    return img0.fileID < img1.fileID
})
//let sortedImages = images.sorted { $0.fileID < $1.fileID } // also works
print(sortedImages)

/*
 prints: [ImageFile with ID: 300, ImageFile with ID: 200, ImageFile with ID: 100]
 */

नोट स्विफ्ट ने दो तरीकों कहा जाता है प्रदान करता है कि sort()और sort(by:)के समकक्षों के रूप में sorted()और sorted(by:)आप इन-जगह अपने संग्रह सॉर्ट करने के लिए की जरूरत है।



20

आप भी कुछ ऐसा कर सकते हैं

images = sorted(images) {$0.fileID > $1.fileID}

इसलिए आपकी छवियों की सरणी को सॉर्ट किया जाएगा


19

4 के माध्यम से 2 स्विफ्ट

कुछ संपत्ति का उपयोग करके कस्टम वस्तुओं की एक सरणी को सॉर्ट करने के लिए मूल उत्तर की मांग की गई। नीचे मैं आपको ऐसे ही व्यवहार डब्ल्यू / स्विफ्ट डेटा संरचनाओं को करने के लिए कुछ आसान तरीके दिखाऊंगा!

छोटी चीजें इस तरह से आगे बढ़ती हैं, मैंने इमेजफाइल को कभी भी थोड़ा बदल दिया। इसे ध्यान में रखते हुए, मैं तीन छवि फ़ाइलों के साथ एक सरणी बनाता हूं । ध्यान दें कि मेटाडेटा एक वैकल्पिक मूल्य है, एक पैरामीटर के रूप में एनआईएल में गुजरना अपेक्षित है।

 struct ImageFile {
      var name: String
      var metadata: String?
      var size: Int
    }

    var images: [ImageFile] = [ImageFile(name: "HelloWorld", metadata: nil, size: 256), ImageFile(name: "Traveling Salesmen", metadata: "uh this is huge", size: 1024), ImageFile(name: "Slack", metadata: "what's in this stuff?", size: 2048) ]

ImageFile का एक गुण है जिसका नाम आकार है। निम्नलिखित उदाहरणों के लिए मैं आपको दिखाऊंगा कि आकार की तरह w / संपत्तियों का उपयोग कैसे करें।

सबसे बड़े आकार का सबसे छोटा (<)

    let sizeSmallestSorted = images.sorted { (initial, next) -> Bool in
      return initial.size < next.size
    }

सबसे बड़ी से छोटी (>)

    let sizeBiggestSorted = images.sorted { (initial, next) -> Bool in
      return initial.size > next.size
    }

आगे हम स्ट्रिंग प्रॉपर्टी नाम का उपयोग करेंगे। उसी तरह, स्ट्रिंग्स की तुलना करने के लिए सॉर्ट का उपयोग करें। लेकिन ध्यान दें कि इनर ब्लॉक एक तुलनात्मक परिणाम देता है। यह परिणाम क्रम को परिभाषित करेगा।

AZ (.orderedAscending)

    let nameAscendingSorted = images.sorted { (initial, next) -> Bool in
      return initial.name.compare(next.name) == .orderedAscending
    }

ZA (.orderedescending)

    let nameDescendingSorted = images.sorted { (initial, next) -> Bool in
      return initial.name.compare(next.name) == .orderedDescending
    }

इसके बाद सॉर्ट करने का मेरा पसंदीदा तरीका है, कई मामलों में एक में वैकल्पिक गुण होंगे। अब चिंता मत करो, हम ऊपर के रूप में उसी तरह से सॉर्ट करने जा रहे हैं, सिवाय इसके कि हमें शून्य को संभालना है! उत्पादन में;

मैंने इस कोड का उपयोग अपने संपत्ति के सभी उदाहरणों को शून्य संपत्ति मानों के साथ अंतिम रूप से बाध्य करने के लिए किया। फिर ग्रहण किए गए अलिखित मानों का उपयोग करके मेटाडेटा का आदेश दें।

    let metadataFirst = images.sorted { (initial, next) -> Bool in
      guard initial.metadata != nil else { return true }
      guard next.metadata != nil else { return true }
      return initial.metadata!.compare(next.metadata!) == .orderedAscending
    }

वैकल्पिक के लिए एक द्वितीयक प्रकार होना संभव है। उदाहरण के लिए; कोई मेटाडेटा के साथ चित्र दिखा सकता है और आकार के अनुसार आदेशित किया जा सकता है।


1
आम तौर पर, उत्तर बहुत अधिक सहायक होते हैं यदि वे एक स्पष्टीकरण शामिल करते हैं कि कोड क्या करने का इरादा है, और क्यों वह दूसरों को पेश किए बिना समस्या को हल करता है।
टॉम अरंडा

बहुत बेहतर।
टॉम अरंडा

18

दो विकल्प

1) SortInPlace के साथ मूल सरणी का आदेश देना

self.assignments.sortInPlace({ $0.order < $1.order })
self.printAssignments(assignments)

2) आदेशित सरणी को संग्रहीत करने के लिए एक वैकल्पिक सरणी का उपयोग करना

var assignmentsO = [Assignment] ()
assignmentsO = self.assignments.sort({ $0.order < $1.order })
self.printAssignments(assignmentsO)

3
2) खाली सरणी बनाने और उसे अगली पंक्ति में छोड़ने का क्या मतलब है? मैं सबसे अधिक उपयोग करके var assignmentsO : [Assignment]या इसे एक पंक्ति में जोड़कर उपयोग करूँगाlet assignmentsO = self.assignments.sort({ $0.order < $1.order })
हरमन क्लेकर

2
हाय हरमन! पढ़ने योग्य और कुशल कोड लिखने के बीच एक बहुत पतली रेखा है। इस मामले में, एकमात्र बिंदु इसे समुदाय के लिए अधिक पठनीय बना रहा है;) आनंद लें!
बर्नॉयर

18

स्विफ्ट 4.0, 4.1 और 4.2 सबसे पहले, मैंने नीचे दिखाए गए प्रकार की छवि () के रूप में उत्परिवर्तित सरणी बनाई

var arr = [imageFile]()

प्रकार की छवि की परस्पर वस्तु छवि बनाएं () और नीचे दिखाए गए अनुसार गुणों को मान प्रदान करें

   var image = imageFile()
   image.fileId = 14
   image.fileName = "A"

अब, इस ऑब्जेक्ट को अरेस्ट अरेस्ट करें

    arr.append(image)

अब, अलग-अलग गुणों को एक ही म्यूटेबल ऑब्जेक्ट यानी छवि पर असाइन करें

   image = imageFile()
   image.fileId = 13
   image.fileName = "B"

अब, फिर से अरैस्ट अरेस्ट के लिए इमेज ऑब्जेक्ट को जोड़ें

    arr.append(image)

अब, हम एरर अरेस्ट ऑब्जेक्ट्स में fileId प्रॉपर्टी पर Ascending ऑर्डर लागू करेंगे । आरोही क्रम के लिए <प्रतीक का उपयोग करें

 arr = arr.sorted(by: {$0.fileId < $1.fileId}) // arr has all objects in Ascending order
 print("sorted array is",arr[0].fileId)// sorted array is 13
 print("sorted array is",arr[1].fileId)//sorted array is 14

अब, हम एरर अरेस्ट ऑब्जेक्ट्स में fileId प्रॉपर्टी पर अवरोही क्रम लागू करेंगे । उपयोग > अवरोही क्रम के लिए प्रतीक

 arr = arr.sorted(by: {$0.fileId > $1.fileId}) // arr has all objects in Descending order
 print("Unsorted array is",arr[0].fileId)// Unsorted array is 14
 print("Unsorted array is",arr[1].fileId)// Unsorted array is 13

स्विफ्ट में 4.1। & 4.2 क्रमबद्ध उपयोग के लिए

let sortedArr = arr.sorted { (id1, id2) -> Bool in
  return id1.fileId < id2.fileId // Use > for Descending order
}

8

यदि आप इस सरणी को एक से अधिक स्थानों पर क्रमबद्ध करने जा रहे हैं, तो यह आपके सरणी प्रकार को तुलना करने योग्य बना सकता है।

class MyImageType: Comparable, Printable {
    var fileID: Int

    // For Printable
    var description: String {
        get {
            return "ID: \(fileID)"
        }
    }

    init(fileID: Int) {
        self.fileID = fileID
    }
}

// For Comparable
func <(left: MyImageType, right: MyImageType) -> Bool {
    return left.fileID < right.fileID
}

// For Comparable
func ==(left: MyImageType, right: MyImageType) -> Bool {
    return left.fileID == right.fileID
}

let one = MyImageType(fileID: 1)
let two = MyImageType(fileID: 2)
let twoA = MyImageType(fileID: 2)
let three = MyImageType(fileID: 3)

let a1 = [one, three, two]

// return a sorted array
println(sorted(a1)) // "[ID: 1, ID: 2, ID: 3]"

var a2 = [two, one, twoA, three]

// sort the array 'in place'
sort(&a2)
println(a2) // "[ID: 1, ID: 2, ID: 2, ID: 3]"

6

यदि आप कस्टम ऑब्जेक्ट्स का उपयोग नहीं कर रहे हैं, लेकिन इसके बजाय मान टाइप करें जो तुलनात्मक प्रोटोकॉल को लागू करता है (Int, String etc ..) आप इसे कर सकते हैं:

myArray.sort(>) //sort descending order

एक उदाहरण:

struct MyStruct: Comparable {
    var name = "Untitled"
}

func <(lhs: MyStruct, rhs: MyStruct) -> Bool {
    return lhs.name < rhs.name
}
// Implementation of == required by Equatable
func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
    return lhs.name == rhs.name
}

let value1 = MyStruct()
var value2 = MyStruct()

value2.name = "A New Name"

var anArray:[MyStruct] = []
anArray.append(value1)
anArray.append(value2)

anArray.sort(>) // This will sort the array in descending order

स्विफ्ट 3 में यह हैmyArray.sorted(by: >)
beryllium

6

आप फ़ाइलआईडी प्रॉपर्टी से निम्न प्रकार से क्रमबद्ध सरणी लौटाते हैं:

स्विफ्ट 2

let sortedArray = images.sorted({ $0.fileID > $1.fileID })

स्विफ्ट 3 या 4

let sortedArray = images.sorted(by: { $0.fileID > $1.fileID })

स्विफ्ट 5.0

let sortedArray = images.sorted {
    $0.fileID < $1.fileID
}

एक आकर्षण की तरह काम करता है .. उत्थान! (प्रतीक प्रजापति, अहमदाबाद)
NSPratik


2

यदि आप कस्टम ऑब्जेक्ट की मूल सरणी को सॉर्ट करना चाहते हैं। यहाँ स्विफ्ट 2.1 में ऐसा करने का एक और तरीका है

var myCustomerArray = [Customer]()
myCustomerArray.sortInPlace {(customer1:Customer, customer2:Customer) -> Bool in
    customer1.id < customer2.id
}

idइंटेगर कहां है आप संपत्तियों के <लिए भी उसी ऑपरेटर का उपयोग कर सकते हैं String

आप यहां इसके उदाहरण के बारे में अधिक जानकारी प्राप्त कर सकते हैं: Swift2: नियर ग्राहक



1

स्विफ्ट 3 और 4 और 5

मुझे लोअरकेस और कैपिटल केस से संबंधित कुछ समस्या थी

इसलिए मैंने इस कोड को किया

let sortedImages = images.sorted(by: { $0.fileID.lowercased() < $1.fileID.lowercased() })

और फिर उसके बाद SortedImages का उपयोग करें


0

KeyPath का उपयोग करके सॉर्ट करें

आप KeyPathइस तरह से सॉर्ट कर सकते हैं :

myArray.sorted(by: \.fileName, <) /* using `<` for ascending sorting */

इस छोटे से उपयोगी विस्तार को लागू करके।

extension Collection{
    func sorted<Value: Comparable>(
        by keyPath: KeyPath<Element, Value>,
        _ comparator: (_ lhs: Value, _ rhs: Value) -> Bool) -> [Element] {
        sorted { comparator($0[keyPath: keyPath], $1[keyPath: keyPath]) }
    }
}

होप स्विफ्ट भाषा के मूल में निकट भविष्य में इसे जोड़ते हैं।


यह पहले से ही यहां बताया गया है stackoverflow.com/a/46601105/2303865 और साथ ही उत्परिवर्तन विधि के साथ।
सिंह दबस

उत्परिवर्तन संस्करणpublic extension MutableCollection where Self: RandomAccessCollection { mutating func sort<T>(_ keyPath: KeyPath<Element, T>, by areInIncreasingOrder: (T, T) throws -> Bool) rethrows where T: Comparable { try sort { try areInIncreasingOrder($0[keyPath: keyPath], $1[keyPath: keyPath]) } }}
लियो डबस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.