четверг, 15 ноября 2012 г.

Objective-C. Массивы NSArray и NSMutableArray.

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

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


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

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 вы всегда можете ознакомится в документации.

Комментариев нет:

Отправить комментарий