Массивы в Objective-C. NSArray и NSMutableArray
АВТОР LIMEJELLY
21.09.2011
Массивы в 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 вы всегда можете ознакомится в документации.
No comments:
Post a Comment