Відповіді:
Коли порядок елементів у колекції не важливий, набори пропонують кращі показники пошуку предметів у колекції.
Причина полягає в тому, що набір використовує хеш-значення для пошуку елементів (наприклад, словник), тоді як масив повинен перебирати весь вміст, щоб знайти певний об'єкт.
Зображення з Документації Apple дуже добре описує це:
Array
- впорядкована (порядок підтримується при додаванні) послідовності елементів
[array addObject:@1];
[array addObject:@2];
[array addObject:@3];
[array addObject:@4];
[array addObject:@6];
[array addObject:@4];
[array addObject:@1];
[array addObject:@2];
[1, 2, 3, 4, 6, 4, 1, 2]
Set
це чіткий (без дублікатів), не упорядкований список елементів
[set addObject:@1];
[set addObject:@2];
[set addObject:@3];
[set addObject:@4];
[set addObject:@6];
[set addObject:@4];
[set addObject:@1];
[set addObject:@2];
[1, 2, 6, 4, 3]
Найкраща відповідь на це - власна документація Apple .
Основна відмінність полягає в тому, що NSArray
для замовленої колекції таNSSet
для колекції, .
Є кілька статей, які розповідають про різницю швидкості між цими двома, як ця . Якщо ви повторюєте невпорядковану колекцію, NSSet
це чудово. Однак у багатьох випадках вам потрібно робити речі, які тільки NSArray
вміє робити, тому ви жертвуєте швидкістю для цих здібностей.
NSSet
NSArray
Це все, що насправді є! Дайте мені знати, якщо це допомагає.
NSSet
заради індексації. Для одних і тих же даних прийнято використовувати дві різні структури даних. Або ви будуєте та індексуєте цей масив :) Але тоді краще використовувати БД, в якій реалізовано alredy.
NSSet
і NSArray
, моя відповідь точна і повна. Так, ви можете створювати інші структури даних, але я лише порівнюю ці дві.
NSArray
та певна функціональність NSSet
, правильна відповідь - це не "використання NSArray
та жертвоприношення". Відповідь - поєднати обидва або використовувати іншу структуру даних.
Масив використовується для доступу до елементів за їх індексом. Будь-який елемент можна вставити в масив кілька разів. Масиви підтримують порядок їх елементів.
Набір використовується в основному лише для перевірки, чи є предмет у колекції чи ні. Елементи не мають поняття порядку чи індексації. Ви не можете мати предмет у наборі двічі.
Якщо масив хоче перевірити, чи містить він елемент, він повинен перевірити всі його елементи. Набори розроблені для використання більш швидких алгоритмів.
Ви можете уявити набір як словник без значень.
Зауважте, що масив і набір - не єдині структури даних. Є й інші, наприклад, черга, стек, купа, купа Фібоначчі. Я рекомендую прочитати книгу про алгоритми та структури даних.
Додаткову інформацію див. У wikipedia .
contains
операції така O(n)
. Кількість порівнянь, коли їх немає в масиві n
. Середня кількість порівнянь, коли об’єкт знаходиться в масиві, є n/2
. Навіть якщо об’єкт знайдений, вистава жахлива.
NSArray
s мають інші переваги швидкості порівняно з NSSet
s. Як завжди, це компроміс.
NSArray *Arr;
NSSet *Nset;
Arr=[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"2",@"1", nil];
Nset=[NSSet setWithObjects:@"1",@"2",@"3",@"3",@"5",@"5", nil];
NSLog(@"%@",Arr);
NSLog(@"%@",Nset);
масив
2015-12-04 11: 05: 40.935 [598: 15730] (1, 2, 3, 4, 2, 1)
набір
2015-12-04 11: 05: 43,362 [598: 15730] {(3, 1, 2, 5)}
Основні відмінності вже наведені в інших відповідях.
Я хотів би лише зазначити, що через те, як реалізуються набори та словники (тобто використовуються хеші), слід бути обережним, щоб не використовувати змінні об’єкти для клавіш.
Якщо ключ мутований, хеш (ймовірно) також зміниться, вказуючи на інший індекс / відро в хеш-таблиці. Вихідне значення не буде видалено, і воно буде фактично враховано при перерахуванні або запитуванні структури про її розмір / кількість.
Це може призвести до появи справді важких помилок.
Тут ви можете знайти досить ретельне порівняння структур NSArray
та NSSet
даних.
Короткі висновки:
Так, NSArray швидше, ніж NSSet, просто утримуючи та повторюючи. Всього 50% швидше для побудови і так само 500% швидше для ітерації. Урок: якщо вам потрібно лише повторити вміст, не використовуйте NSSet.
Звичайно, якщо вам потрібно протестувати на включення, працюйте наполегливо, щоб уникнути NSArray. Навіть якщо вам потрібна ітерація, і тестування включення, ви, ймовірно, все ж повинні вибрати NSSet. Якщо вам потрібно впорядкувати колекцію впорядкованою, а також перевірити на включення, тоді слід розглянути можливість збереження двох колекцій (NSArray та NSSet), кожна з яких містить однакові об'єкти.
NSDictionary будується повільніше, ніж NSMapTable - оскільки йому потрібно скопіювати ключові дані. Він компенсує це тим, що швидше шукати. Звичайно, обидва мають різні можливості, тому більшу частину часу це визначення слід проводити з інших факторів.
Зазвичай ви використовуєте набір, коли швидкість доступу є суттєвою, а порядок не має значення , або визначається іншими способами (через дескриптор предиката або сортування). Наприклад, Core Data використовує набори, коли доступ до керованих об'єктів здійснюється через відношення до багатьох
Просто для додання трохи цього я використовую набір іноді просто для видалення дублікатів з масиву на зразок: -
NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values