Array sortieren und case sensitive

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Array sortieren und case sensitive

    Hallo,

    ich such mir gerade einen Wolf nach der Lösung zu meinem aktuellen Problem...

    Ich habe ein Array was ich sortieren möchte.
    Machte das mit self.arrayname.sortInPlace()
    Leider gibt es da case sensitive Probleme.

    Anton
    Gustaf
    Martin
    Zeus
    manuel
    simon


    Irgendwie versteckt sich die Lösung das ganze unabhängig von Groß-/Kleinschreibung zu sortieren.

    Kann mir jemand den entscheidenden Tipp geben?

    Gruß

    Manitwo
  • Manitwo schrieb:


    So sieht meine Lösung aus...

    Quellcode

    1. self.daten.sortInPlace({
    2. $0.caseInsensitiveCompare($1) == NSComparisonResult.OrderedAscending
    3. })
    Gibt es da was auszusetzen?

    Absolut nicht. Genau so.

    Es geht allerdings noch etwas kürzer und lesbarer:

    1.) Auf self kann man in der Regel verzichten. Hängt vom Geschmack und Kontext ab, ob Code mit oder ohne lesbarer und verständlicher ist.

    2.) Bei closures als einzigem Parameter kann man auf die runden Klammern verzichten.

    3.) Wegen der Typ inference kann man die Typangabe NSComparisonResult weglassen.

    Das sähe dann so aus:

    Quellcode

    1. daten.sortInPlace{ $0.caseInsensitiveCompare($1) == .OrderedAscending }

    Eine schlechtere Alternative wäre noch folgendes gewesen:

    Quellcode

    1. daten.sortInPlace{ $0.lowercaseString < $1.lowercaseString }
  • tsunamix schrieb:

    MCDan schrieb:

    "Keep it simply" wurde bei Apple, zusammen mit Steve Jobs, leider zu Grabe getragen. :(
    Du meinst bestimmt "simple". ;)
    Ups, vertippt. Habe dies mal korrigiert.

    Ist sortInPlace eine neue Methode von NSArray, die es nur in Swift gibt oder warum kann/sollte man nicht die Swift Version von

    Quellcode

    1. [self.arrayname sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    verwenden?

    Wie würde dies in Swift Syntax aussehen? Vielleicht verstehe ich Swift dann doch irgendwann noch mal. ?(
  • MCDan schrieb:

    Ist sortInPlace eine neue Methode von NSArray, die es nur in Swift gibt oder warum kann/sollte man nicht die Swift Version von
    Das ist eine Methode von Array. In-Place-Sortierung wäre auch allenfalls bei NSMutableArray funktionieren.

    MCDan schrieb:

    Wie würde dies in Swift Syntax aussehen?
    Im Prinzip ähnlich wie in Objective-C. Da Swift keine Selektoren kennt, muss man dafür Strings verwenden.

    Quellcode

    1. array = array.sortedArrayUsingSelector("caseInsensitiveCompare:")
    Geht aber so nur mit Objective-C-Klassen.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    Im Prinzip ähnlich wie in Objective-C. Da Swift keine Selektoren kennt, muss man dafür Strings verwenden.

    Quellcode

    1. array = array.sortedArrayUsingSelector("caseInsensitiveCompare:")

    Geht aber so nur mit Objective-C-Klassen.

    Jein. Das ist so nicht ganz richtig. Erstmal kompiliert der Code nicht. Es bedarf eines Casts nach NSArray. Nach NSMutableArray kann man nicht casten. Also, das sieht dann so aus:

    Quellcode

    1. var daten = ["Anton", "Gustaf", "Martin", "Zeus", "manuel", "simon"]
    2. var array = (daten as NSArray).sortedArrayUsingSelector("caseInsensitiveCompare:")

    Aber vorsicht! Aus dem eingehenden String-Array [String] erhält man plötzlich ein Array mit AnyObjects zurück, also [AnyObject]. Hinter dem AnyObject verbergen sich jetzt lauter NSStrings und keine Swift Strings. Klar. Weil man auf Swift Strings keine Selektoren anwenden kann, muß zu NSString konvertiert werden. Die im Array enthaltenen NSStrings sind zu allem Überfluß jetzt auch noch unveränderlich.

    Die Syntax, wie man in Swift Obj-C Selektoren anspricht, wird sich in Swift 2.2 (oder 3.0, hab ich gerade nicht im Kopf) ändern. Aus einem einfachen String wird dann sowas wie #selector(nameOfMethod).
  • Jaaa... Das habe ich bemerkt. Ich sagte ja auch 'Jein', nicht etwa 'Nein'.

    Das Ausgangsobjekt muß keine ObjC-Klasse sein, wie z.B. ein NS{Mutable}Array mit NSString, bzw. AnyObject als Elemente. Es geht eben mit einem Swift-Typ, der keine Klasse sein muß, wie einem [String]-Array. Aber dazu und dann geht es in die Swift/ObC-Bridging-Welt (Hölle?) mit einigen Verrenkungen und Überaschungen. Das wollte ich nur (auch für mich selbst) ergänzend noch etwas herausarbeiten. Mir ging es nicht darum, Deine Aussage zu kritisieren, abgesehen vielleich davon, daß das Codebeispiel nicht kompiliert.^^ Du hast ja – sehr knapp – die relevanten Punkte erwähnt.

    Die Objective-C-Runtime ist jedenfalls zwingend nötig. Die OS Foundation-Implementierung, bei der es keine Objective-C-Runtime gibt, kennt deshalb auch keine Selektoren und diese Methoden/Funktionen deshalb natürlich auch nicht...
  • tsunamix schrieb:

    Das Ausgangsobjekt muß keine ObjC-Klasse sein, wie z.B. ein NS{Mutable}Array mit NSString, bzw. AnyObject als Elemente.
    Mit dem zugegebenermaßen etwas krummen Begriff meinte ich nicht nur Klassen, die aus Objective-C stammen, sondern auch Swift-Klassen, die das Objective-C-Message-Passing beherrschen. Das lässt sich meines Wissens auch über das Attribut @objc erreichen.

    tsunamix schrieb:

    Deine Aussage zu kritisieren, abgesehen vielleich davon, daß das Codebeispiel nicht kompiliert.^^
    Das hängt ja von array ab, dessen Deklaration in meinem Listing fehlt und in denen des OPs nicht auftaucht. ;)

    tsunamix schrieb:

    Die OS Foundation-Implementierung, bei der es keine Objective-C-Runtime gibt, kennt deshalb auch keine Selektoren und diese Methoden/Funktionen deshalb natürlich auch nicht...
    Falls du dich mit OS Foundation-Implementierung auf die Swift-Implementierung von Foundation beziehst: Darin fehlt die Implementierung von sortedArrayUsingSelector:. Eine reine Swift-Implementierung dieser Methode dürfte auch extrem schwierig sein.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    tsunamix schrieb:

    Das Ausgangsobjekt muß keine ObjC-Klasse sein, wie z.B. ein NS{Mutable}Array mit NSString, bzw. AnyObject als Elemente.
    Mit dem zugegebenermaßen etwas krummen Begriff meinte ich nicht nur Klassen, die aus Objective-C stammen, sondern auch Swift-Klassen, die das Objective-C-Message-Passing beherrschen. Das lässt sich meines Wissens auch über das Attribut @objc erreichen.

    Es geht eben auch mit Swift-Typen, die gar keine Klassen sind. Du weißt doch, daß das Swift-Array und -String als struct implementiert sind. Das sind keine Klassen.

    Es geht auch mit Int. Auch bei solch einem primitiven Wertetyp wird interessanterweise in den entsprechenden Cocoa-Klassentyp konvertiert. Hab's selber nach o.g. Muster mal ausprobiert:

    Quellcode

    1. var nums = [7, 3, 5, 4, 1, 9, 2]
    2. print(nums) // [7, 3, 5, 4, 1, 9, 2]
    3. print(String(nums.dynamicType)) // Array<Int>
    4. print(String(nums[0].dynamicType)) // Int
    5. var sortedNSNums = (nums as NSArray).sortedArrayUsingSelector("compare:")
    6. print(sortedNSNums) // [1, 2, 3, 4, 5, 7, 9]
    7. print(String(sortedNSNums.dynamicType)) // Array<AnyObject>
    8. print(String(sortedNSNums[0].dynamicType)) // __NSCFNumber
    Alles anzeigen

    Mit diesem @objc kenne ich mich zugegebenermaßen nicht aus, aber natürlich wichtig für diese Swift/ObjC-Bridge...

    macmoonshine schrieb:

    tsunamix schrieb:

    Deine Aussage zu kritisieren, abgesehen vielleich davon, daß das Codebeispiel nicht kompiliert.^^
    Das hängt ja von array ab, dessen Deklaration in meinem Listing fehlt und in denen des OPs nicht auftaucht. ;)

    OK. Normalerweise würde man ja von einem Swift-Array ausgehen, aber den Punkt laß ich Dir. :)

    macmoonshine schrieb:

    tsunamix schrieb:

    Die OS Foundation-Implementierung, bei der es keine Objective-C-Runtime gibt, kennt deshalb auch keine Selektoren und diese Methoden/Funktionen deshalb natürlich auch nicht...
    Falls du dich mit OS Foundation-Implementierung auf die Swift-Implementierung von Foundation beziehst: Darin fehlt die Implementierung von sortedArrayUsingSelector:. Eine reine Swift-Implementierung dieser Methode dürfte auch extrem schwierig sein.

    Jup. Genau das meinte ich ja.^^
  • tsunamix schrieb:

    Es geht eben auch mit Swift-Typen, die gar keine Klassen sind. Du weißt doch, daß das Swift-Array und -String als struct implementiert sind. Das sind keine Klassen.
    __NSCFNumber ist eine (Unter-)Klasse des Classclusters NSNumber und somit eine Objective-C-Klasse! Objective-C-Containerklassen können keine Swift-Structs speichern.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    tsunamix schrieb:

    Es geht eben auch mit Swift-Typen, die gar keine Klassen sind. Du weißt doch, daß das Swift-Array und -String als struct implementiert sind. Das sind keine Klassen.
    __NSCFNumber ist eine (Unter-)Klasse des Classclusters NSNumber und somit eine Objective-C-Klasse!

    Bitte, macmoonshine, verkauf mich nicht für blöde. Ich habe nicht erst gestern mit Swift angefangen, ich bin seit ca. 15 Jahren mit Objective-C dabei. Ich kenne die Datentypen!

    Es ging mir darum:

    1.) welche Datentypen gehen rein
    2.) was passiert (möglicherweise in der Bridge)
    3.) welche Datentypen kommen raus

    @ 1.) Native Swift Typen gehen
    @ 2.) ???
    @ 3.) Mischmasch

    macmoonshine schrieb:

    Objective-C-Containerklassen können keine Swift-Structs speichern.
    Der Witz an der Sache ist doch, daß anschließend gar keine Objective-C-Containerklassen wie ein NSArray dabei rauskommen, sondern ein natives Swift-Array Array<AnyObject>! Im Gegensatz zu reinem Objective-C-Code (und der API-Definition) ist das dann sogar wieder mutable. WTF!?

    Wir können da noch lange drüber philosophieren, in Swift würde, bzw. sollte man nicht auf diese Methoden mit Selektoren zurückgreifen.^^
  • tsunamix schrieb:

    Bitte, macmoonshine, verkauf mich nicht für blöde. Ich habe nicht erst gestern mit Swift angefangen, ich bin seit ca. 15 Jahren mit Objective-C dabei. Ich kenne die Datentypen!

    Es ging mir darum:

    1.) welche Datentypen gehen rein
    2.) was passiert (möglicherweise in der Bridge)
    3.) welche Datentypen kommen raus
    Es geht darum, an welche Entitäten man Selektoren schicken kann, und das geht nur an Objekte die Objective-C-Eigenschaften haben. Das ist die ganze Zeit meine Aussage und etwas anderes habe ich nicht behauptet. Ich weiß nicht, was du in meine Aussagen hineininterpretierst.

    Du schriebst

    tsunamix schrieb:

    Es geht eben auch mit Swift-Typen, die gar keine Klassen sind. Du weißt doch, daß das Swift-Array und -String als struct implementiert sind. Das sind keine Klassen.
    und sage: Nein, das stimmt nicht. Swift hat die Zahlen in deinem Array in NSNumber-Objekte umgewandelt, was du durch deinen Beispielcode sogar selber bewiesen hast.
    „Meine Komplikation hatte eine Komplikation.“