Programmieren mit Swift - Für macOS und iOS
Programmieren mit Swift - Für macOS und iOS
Ein Array sortieren

Möchte man ein Array mit Bubblesort oder einem anderen Algorithmus sortieren, ist es dafür immer zwingend notwendig, einzelne Objekte innerhalb des Arrays gegeneinander auszutauschen. Für die Klasse NSMutableArray übernimmt das die Methode exchangeObjectAtIndex, mit der immer zwei Objekte an ihren Positionen getauscht werden
NSMutableArray *myArray;
myArray = [
NSMutableArray arrayWithCapacity:3];

[myArray
addObject:@"Alpha"];
[myArray
addObject:@"Beta"];
[myArray
addObject:@"Gamma"];

[myArray exchangeObjectAtIndex:
2 withObjectAtIndex:0];

for(int i = 0; i < [myArray count]; i++)
{

    NSLog
(@"Index %d ist %@", i, [myArray objectAtIndex:i]);
}
stacks_image_8F8A1BD5-FC56-4A20-A62B-E9513A670C92
Möchte man hingegen ein Objekt innerhalb des Arrays ersetzten, funktioniert das mit der Methode replaceObjectAtIndex.
[myArray replaceObjectAtIndex:1 withObject:@"Delta"];
Mit diesen beiden Methoden sollte es jetzt kein Problem mehr darstellen, das Array nach Belieben zu manipulieren. Möchte man ein NSMutableArray tatsächlich sortieren, muss man sich aber nicht die Mühe machen, das selbst zu programmieren. Die Klasse hat eigene Möglichkeiten, um ihren Inhalt nahezu automatisch zu sortieren. Die einfachste ist sortUsingSelector.
NSMutableArray *myArray;
myArray = [
NSMutableArray arrayWithCapacity:3];

[myArray
addObject:@"Gamma"];
[myArray
addObject:@"Alpha"];
[myArray
addObject:@"Beta"];

[myArray sortUsingSelector:
@selector(compare:)];

for(int i = 0; i < [myArray count]; i++)
{

    NSLog
(@"Index %d ist %@", i, [myArray objectAtIndex:i]);
}
Durch den Aufruf von sortUsingSelector wird ein Array mit Zeichenketten automatisch aufsteigend sortiert und dabei zum Vergleich die Methode compare der Klasse NSString verwendet. In Objective-C werden Methoden auch als Selektor bezeichnet und daher bedeutet sortUsingSelector nichts anderes als „Sortiere mit Hilfe der Methode“. Dabei muss eine Klasse natürlich eine compare-Methode anbieten, mit der Objekte verglichen werden können.

Möchte man ein Array ganz anders sortieren, vielleicht wenn Objekte vom Typ Person im Array sind und man nur nach den Nachnamen sortieren möchte, kann für die Klasse eine eigene compare-Methode implementiert werden. Als Alternative erweisen sich auch eigene Sortierfunktionen als sinnvoll. Wie in der Funktion verglichen wird, ist dann ganz dem Programmierer überlassen, wichtig ist nur, dass die Rückgabewerte einer solchen Funktion einem NSComparisonResult/NSInteger entsprechen.
NSNumber *n1 = [NSNumber numberWithInt:123];
NSNumber *n2 = [NSNumber numberWithInt:
38];
NSNumber *n3 = [NSNumber numberWithInt:
7];
NSNumber *n4 = [NSNumber numberWithInt:
45];
NSNumber *n5 = [NSNumber numberWithInt:
99];
NSNumber *n6 = [NSNumber numberWithInt:
71];

NSMutableArray *myArray;
myArray = [NSMutableArray arrayWithObjects:n1,n2,n3,n4,n5,n6,
nil];

[myArray sortUsingFunction:compareFunction context:
NULL];

for(int i = 0; i < [myArray count]; i++)
{
    NSLog(
@"Index %d ist %d",i, [[myArray objectAtIndex:i] intValue] );
}
Die Funktion compareFunction, in der jeweils zwei Objekte des Array verglichen werden, könnte für eine Sortierung dieses NSMutableArray aus Typen von NSNumber so aussehen:
NSInteger compareFunction(id val1,id val2,void *context)
{

    int
nVal1 = [val1 intValue];
    int
nVal2 = [val2 intValue];

    if
(nVal1 < nVal2)
    {

        return
NSOrderedAscending ;
    }

    else
if(nVal1 > nVal2)
    {

        return
NSOrderedDescending;
    }

    return
NSOrderedSame;
}
stacks_image_BCB83661-B5A2-4175-9EA2-D541B990DCBE
Die beschriebene Funktion sortiert das Array auch aufsteigend. Will man die Sortierrichtung umkehren, reicht es, die Rückgabewerte in den beiden Blöcken der if-Struktur zu vertauschen.

Eine etwas elegantere Lösung bietet hingegen der context, der als Parameter mit in die Funktion übergeben werden kann. Er ermöglicht es, von außen eine Sortierrichtung anzugeben. Im folgenden Beispiel soll der context ein NSString sein.
NSInteger otherCompareFunction(id val1,id val2,void *context)
{

    int
nVal1 = [val1 intValue];
    int
nVal2 = [val2 intValue];

    NSString
*order = context;

    if
([order compare:@"auf"] == NSOrderedSame)
    {

        if
(nVal1 < nVal2)
        {

            return
NSOrderedAscending;
        }

        else
if(nVal1 > nVal2)
        {

            return
NSOrderedDescending;
        }
    }

    else

    {

        if
(nVal1 < nVal2)
        {

             return
NSOrderedDescending;
        }

        else
if(nVal1 > nVal2)
        {

            return
NSOrderedAscending;
        }
    }

    return
NSOrderedSame;
}
Der Aufruf einer solchen Sortierfunktion wäre dann wie folgt:
[myArray sortUsingFunction:otherCompareFunction context:@"ab"];
Möchte man das Array weiterhin aufsteigend sortieren, ist die richtige Anweisung:
[myArray sortUsingFunction:otherCompareFunction context:@"auf"];