¿Cuándo es mejor usar un NSSet sobre un NSArray?


He utilizado NSSets muchas veces en mis aplicaciones, pero nunca he creado uno yo mismo.

Mi pregunta es:

¿Cuándo es mejor usar un NSSet a diferencia de un NSArray ¿y por qué?

Author: James Webster, 2012-06-12

11 answers

Cuando el orden de los elementos de la colección no es importante, los conjuntos ofrecen un mejor rendimiento para encontrar elementos de la colección.

La razón es que un conjunto utiliza valores hash para encontrar elementos (como un diccionario) mientras que una matriz tiene que iterar sobre todo su contenido para encontrar un objeto en particular.

 161
Author: Ole Begemann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-03 13:15:29

La imagen de La Documentación de Apple la describe muy bien:

Colecciones Objective-C

Array es una ordenada (el orden se mantiene cuando se agrega) secuencia de elementos

[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 is a distinct (no duplicates), unordered list of elements

[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]
 174
Author: James Webster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-24 08:41:37

La mejor respuesta a esto es La propia documentación de Apple.

introduzca la descripción de la imagen aquí

La principal diferencia es que NSArray es una colección ordenada y NSSet es una colección desordenada.

Hay varios artículos por ahí que hable de la diferencia de velocidad entre los dos, como este. Si estás iterando a través de una colección desordenada, NSSet es genial. Sin embargo, en muchos casos, necesitas hacer cosas que solo un NSArray puede hacer, por lo que sacrificas la velocidad para esas habilidades.

NSSet

  • Principalmente elementos de acceso por comparación
  • Desordenado
  • no permite duplicados

NSArray

  • Puede acceder a los elementos por índice
  • Ordenado
  • Permite duplicados

¡Eso es todo lo que realmente hay! Avísame si eso ayuda.

 64
Author: woz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-07 13:11:49

NSOrderedSet está disponible en iOS 5+, por lo que la principal diferencia es si desea duplicar objetos en la estructura de datos.

 12
Author: Jason,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-08 14:26:54

NSArray :

  1. Recopilación ordenada de datos
  2. Permite duplicados
  3. Es un objeto de tipo colección

NSSet :

  1. Recopilación desordenada de datos
  2. no permite duplicados
  3. También es objeto de tipo colección
 8
Author: iOS Lifee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-08 09:29:57

Se utiliza un array para acceder a los elementos por su índice. Cualquier elemento se puede insertar en la matriz varias veces. Las matrices mantienen el orden de sus elementos.

Un conjunto se utiliza básicamente solo para comprobar si el elemento está en la colección o no. Los ítems no tienen concepto de orden o indexación. No puede tener un elemento en un conjunto dos veces.

Si un array quiere comprobar si contiene un elemento, tiene que comprobar todos sus elementos. Los conjuntos están diseñados para utilizar algoritmos más rápidos.

Puedes imagine un conjunto como un diccionario sin valores.

Tenga en cuenta que array y set no son las únicas estructuras de datos. Hay otros, por ejemplo, Cola, Pila, Montón, Montón de Fibonacci. Recomendaría leer un libro sobre algoritmos y estructuras de datos.

Ver wikipedia para más información.

 7
Author: Sulthan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-12 13:25:37
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);

El array

2015-12-04 11:05:40.935 [598:15730] ( 1, 2, 3, 4, 2, 1 )

El conjunto

2015-12-04 11:05:43.362 [598:15730] { ( 3, 1, 2, 5 )}

 5
Author: abc221,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-01 07:50:40

Las principales diferencias ya se han dado en otras respuestas.

Me gustaría señalar que debido a la forma en que se implementan los conjuntos y diccionarios (es decir,usando hashes), uno debe tener cuidado de no usar objetos mutables para las claves.

Si una clave está mutada, entonces el hash (probablemente) también cambiará, apuntando a un índice/cubo diferente en la tabla hash. El valor original no se eliminará y en realidad se tendrá en cuenta al enumerar o pedir a la estructura su tamaño / cuenta.

Esto puede llevar a algunos errores realmente difíciles de localizar.

 4
Author: joakim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-14 07:36:04

Solo para agregar un poco de ella utilizo set a veces solo para eliminar duplicados de la matriz como: -

NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values
 2
Author: dreamBegin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-23 10:58:51

Aquí puede encontrar una comparación bastante completa de las estructuras de datos NSArray y NSSet.

Conclusiones cortas:

Sí, NSArray es más rápido que NSSet para simplemente mantener e iterar. Tan poco como un 50% más rápido para construir y tanto como un 500% más rápido para iterar. Lección: si solo necesita iterar contenidos, no use un NSSet.

Por supuesto, si necesita probar la inclusión, trabaje duro para evitar NSArray. Incluso si necesita tanto la iteración y prueba de inclusión, probablemente debería elegir un NSSet. Si necesita mantener su colección ordenada y también probar su inclusión, entonces debería considerar mantener dos colecciones (un NSArray y un NSSet), cada una conteniendo los mismos objetos.

NSDictionary es más lento de construir que NSMapTable - ya que necesita copiar los datos clave. Compensa esto siendo más rápido de buscar. Por supuesto, los dos tienen diferentes capacidades por lo que la mayoría de las veces, esta determinación debe ser hecho en otros factores.

 1
Author: Che,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-16 13:10:17

Normalmente se usa un conjunto cuando la velocidad de acceso es esencial y el orden no importa, o está determinado por otros medios (a través de un predicado o un descriptor de ordenación). Core Data, por ejemplo, utiliza conjuntos cuando se accede a objetos administrados a través de una relación a-muchos

 1
Author: iDevAmit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-24 09:38:56