Массивы в Objective-C

В этой статье мы поговорим о массивах. В Objective-C массивы чаще всего реализуются с помощью классов NSArray и NSMutableArray. Класс NSMutableArray, в отличие от NSArray, позволяет произвольно изменять порядок элементов, создавать и удалять новые элементы.

Для вывода результатов будем использовать функцию NSLog(), с которой мы успели поработать в предыдущей статье про NSString. Консоль можно увидеть внизу окна XCode при запуске приложения. Если консоль не открывается, то выберите пункт меню View->Show Debug Area (⇧⌘Y).

Создание массива

Чтобы создать статичный массив с определенным набором элементов можно использовать следующий код:

NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];

NSLog(@"%@", array);

Здесь мы создаем массив с тремя элементами. Элементами являются объекты NSString — т.е. простые строки. Также можем воспользоваться методом initWithArray для создания массива из другого массива:

NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];

NSArray *newArray = [[NSArray alloc] initWithArray:array];
NSLog(@"%@", newArray);

Мы создали полную копию массива. Также мы можем создать массив из другого массива, но использую только часть элементов. Для этого воспользуемся методом subarrayWithRange:

NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];

NSRange range;
range.length = 2;
range.location = 0;
NSArray *newArray = [array subarrayWithRange:range];
NSLog(@"%@", newArray);

В результате мы получим новый массив, который состоит только из первых двух элементов. В следующем примере мы рассмотрим метод initWithContentsOfFile, который позволяет создать массив из файла:

NSString *path = [[NSBundle mainBundle] pathForResource:@"filename" ofType:@"txt"];

NSError *error;
NSArray *array = [[NSArray alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
NSLog(@"%@", array);

Этот метод может показаться вам знакомым по предыдущей статье про строки. Действительно оба класса содержат один и тот же метод, который позволяет создавать объекты с использованием данных, которые могут храниться в файлах. Еще один метод похожий по названию и действию — initWithContentsOfURL, позволяет создать массив использую URL:

NSString *path = @"http://www.apple.com";

NSArray *array = [[NSArray alloc] initWithContentsOfURL:[NSURL URLWithString:path]];
NSLog(@"%@", array);

Не забудьте указать реальный URL, где будет располагаться ваш файл с данными для массива.

Получение данных из массива

В первую очередь рассмотрим простой и очень важный метод count, который позволяет получить количество элементов в массиве:

NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];

NSLog(@"%d", [array count]);

Результатом будет «3». Обратите внимание где мы используем этот метод — непосредственно внутри функции NSLog. Далее рассмотрим пример с использование метода objectAtIndex:

NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];

NSLog(@"%@", [array objectAtIndex:0]);

Этот метод возвращает элемент, который находится на заданном месте. В консоли будет выведен результат «one». Не забывайте что нумерация элементов начинается с нуля.

Поиск элементов в массиве

Самый простой метод поиска элемента в массиве — это containObject:

NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];

if ([array containsObject:@"one"]) {
NSLog(@"yes");
}
else {
NSLog(@"no");
}

Этот метод возвращает FALSE или TRUE в зависимости от того, присутствует или нет элемент внутри массива. В нашем примере на консоли должно появиться «yes». Далее рассмотрим более функциональные методы indexOfObject и indexOfObject:inRange:

NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];

NSLog(@"%d", [array indexOfObject:@"two"]);

и

NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];

NSRange range;
range.length = 2;
range.location = 0;
NSLog(@"%d", [array indexOfObject:@"two"inRange:range]);

Оба метода возвращают номер искомого элемента внутри массива. В первом и во втором примере мы ищем один и тот же элемент «two». Основное отличие заключается в том, что метод indexOfObject:inRange позволяет задать определенный диапазон элементов, где следует проводить поиск.

Сравнение массивов

Простой способ сравнить два массива между собой — использовать метод

NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];

NSArray *newArray = [[NSArray alloc] initWithObjects:@"one", @"two", nil];
if ([array isEqualToArray:newArray]) {
NSLog(@"yes");
}
else {
NSLog(@"no");
}

В консоли должен появиться результат «no» — наши массивы не идентичны друг другу.

Сортировка массивов

Пожалуй самые интересные методы представлены в этом разделе, так как основная задача массивов хранить большое количество элементов, а также дать возможность выбрать из этого массива необходимые данные. Один из способов добраться до необходимых элементов — сортировка. Так как в процессе сортировки расположение элементов в массиве должно изменяться — в наших примерах мы будем использовать массивы класса NSMutableArray. Самый просто способ отсортировать (например массив состоящий из набора чисел) — это использовать метод sortUsingSelector:

NSMutableArray *marray = [[NSMutableArray alloc] init];

for (int i = 0 ; i < 10; i++) {
int newElement = random();
[marray addObject:[NSString stringWithFormat:@"%d",newElement]];
}
NSLog(@"%@", marray);
[marray sortUsingSelector:@selector(compare:)];
NSLog(@"%@", marray);

В цикле for мы наполняем массив случайными значениями (значения хранятся в объектах NSString) и выводим значения в консоль. Далее выполняем сортировку с помощью метода sortUsingSelector. В качестве аргумента мы указали @selector(compare:). Это означает что ортировка выполняется с помощью метода compare класса NSString — именно объекты этого класса мы сравниваем между друг другом. Тоже самое можно реализовать с помощью метода sortUsingDescriptors:

NSMutableArray *marray = [[NSMutableArray alloc] init];

for (int i = 0 ; i < 10; i++) {
int newElement = random();
[marray addObject:[NSString stringWithFormat:@"%d",newElement]];
}
NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:nil ascending:NO selector:@selector(localizedCompare:)];
NSLog(@"%@", marray);
[marray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
NSLog(@"%@", marray);

В данном примере мы задаем специальны дескриптор, который описывает процесс сортировки. Обратите внимание на то, что заменив «ascending:NO» на «ascending:YES», мы получим сортировку по убыванию.

Дополнительные возможности NSMutableArray

При создании массивов часто появляется необходимость добавить новый элемент или удалить ненужный. В этом нам помогут массивы NSMutableArray и их методы, которые позволяют модифицировать массивы «на лету». Инициализовать такой массив мы можем методами перечисленными выше а также можем создать массив без каких либо элементов:

NSMutableArray *marray = [[NSMutableArray alloc] init];

Далее добавляем несколько элементов:

for (int i = 0 ; i < 5; i++) {

[marray addObject:[NSString stringWithFormat:@"element #%d", i]];
}
NSLog(@"%@", marray);

В консоли мы увидим 5 пронумерованных элементов. Также с помощью метода insertObject:atIndex мы свободно можем добавить элемент в массив в любую позицию:

[marray insertObject:@"element #X" atIndex:0];

NSLog(@"%@", marray);

В нашем массиве должен появится еще один элемент в самом начале. Еще востребованный способ добавить элементы в массив — использовать элементы другого массива с помощью метода addObjectsFromArray:

NSArray *array = [[NSArray alloc] initWithObjects:@"one", @"two", @"three", nil];

NSMutableArray *marray = [[NSMutableArray alloc] init];
for (int i = 0 ; i < 5; i++) {
[marray addObject:[NSString stringWithFormat:@"element #%d", i]];
}
[marray insertObject:@"element #X" atIndex:0];
[marray addObjectsFromArray:array];
NSLog(@"%@", marray);

Удалить ненужные элементы можно с помощью нескольких методов. Например — удаляем последний элемент:

NSMutableArray *marray = [[NSMutableArray alloc] init];

for (int i = 0 ; i < 5; i++) {
[marray addObject:[NSString stringWithFormat:@"element #%d", i]];
}
[marray removeLastObject];
NSLog(@"%@", marray);

На выходе получаем только четыре элемента из пяти добавленных. Свободно можем удалить элемент на любой позиции в массиве:

[marray removeObjectAtIndex:0];

Какой-либо конкретный элемент:

[marray removeObject:@"element #1"];

Или все элементы сразу:

[marray removeAllObjects];

А также элементы в заданном диапазоне:

NSMutableArray *marray = [[NSMutableArray alloc] init];

for (int i = 0 ; i < 5; i++) {
[marray addObject:[NSString stringWithFormat:@"element #%d", i]];
}
NSRange range;
range.length = 2;
range.location = 2;
[marray removeObjectsInRange:range];
NSLog(@"%@", marray);

Использование массивов в Objective-C дает большие возможности для хранения, записи, удаления и поиска нужных данных. В то же время работа с массивами не требует глубоких знаний в программировании, все методы простые и интуитивно понятные. Более детально с классами NSArray и NSMutableArray вы всегда можете ознакомится в документации.

Последние статьи

  • [Swift] Урок 1 — Пишем программу «Hello, World» на Swift языке под iOS

  • Audio Unit в iOS. Часть 3, накладываем эффект Delay

  • Audio Unit в iOS. Часть 2, строим граф и проигрываем файлы

  • Audio Unit в iOS. Часть 1, введение.

  • Используем Emoji в своих приложениях

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *