¿La mejor manera de eliminar valores duplicados ( NSString) NSMutableArrayen Objective-C?
¿Es esta la forma más fácil y correcta de hacerlo?
uniquearray = [[NSSet setWithArray:yourarray] allObjects];
ios
objective-c
nsmutablearray
Teo Choong Ping
fuente
fuente

Respuestas:
Su
NSSetenfoque es el mejor si no está preocupado por el orden de los objetos, pero, de nuevo, si no está preocupado por el orden, ¿por qué no los está almacenandoNSSetpara empezar?Escribí la respuesta a continuación en 2009; en 2011, Apple agregó
NSOrderedSeta iOS 5 y Mac OS X 10.7. Lo que había sido un algoritmo ahora son dos líneas de código:Si le preocupa el pedido y está ejecutando iOS 4 o anterior, repita una copia de la matriz:
fuente
[NSOrderedSet orderedSetWithArray:array];Puede recuperar una matriz a través dearray = [orderedSet allObjects];o simplemente usarNSOrderedSets en lugar deNSArrayen primer lugar.[orderedSet allObjects]con[orderedSet array]!NSArrayy debemos crear tempNSMutableArray. En su ejemplo, usted trabaja al revésNSSet) o @Simon Whitaker enlace evitan antes de añadir valor duplicado que es la forma eficiente?Sé que esta es una vieja pregunta, pero hay una forma más elegante de eliminar duplicados en un
NSArraysi no te importa el pedido .Si usamos operadores de objetos de la codificación de valor clave , podemos hacer esto:
Como también señaló AnthoPak , es posible eliminar duplicados en función de una propiedad. Un ejemplo sería:
@distinctUnionOfObjects.namefuente
@distinctUnionOfObjects.propertypara eliminar duplicados por propiedad de una matriz de objetos personalizados. Por ejemplo@distinctUnionOfObjects.nameSí, usar NSSet es un enfoque sensato.
Para agregar a la respuesta de Jim Puls, aquí hay un enfoque alternativo para eliminar los duplicados mientras se mantiene el orden:
Es esencialmente el mismo enfoque que el de Jim, pero copia elementos únicos en una nueva matriz mutable en lugar de eliminar duplicados del original. Esto hace que sea un poco más eficiente en memoria en el caso de una gran matriz con muchos duplicados (no es necesario hacer una copia de toda la matriz), y en mi opinión es un poco más legible.
Tenga en cuenta que, en cualquier caso, verificar si un elemento ya está incluido en la matriz de destino (usando
containsObject:en mi ejemplo, oindexOfObject:inRange:en el de Jim) no escala bien para grandes matrices. Esas comprobaciones se ejecutan en tiempo O (N), lo que significa que si duplica el tamaño de la matriz original, cada comprobación tardará el doble de tiempo en ejecutarse. Como está haciendo la verificación de cada objeto en la matriz, también ejecutará más de esas verificaciones más costosas. El algoritmo general (tanto el mío como el de Jim) se ejecuta en tiempo O (N 2 ), que se vuelve caro rápidamente a medida que crece la matriz original.Para reducir el tiempo a O (N), puede usar a
NSMutableSetpara almacenar un registro de elementos ya agregados a la nueva matriz, ya que las búsquedas de NSSet son O (1) en lugar de O (N). En otras palabras, verificar si un elemento es miembro de un NSSet toma el mismo tiempo, independientemente de cuántos elementos haya en el conjunto.El código que usa este enfoque se vería así:
Sin embargo, esto todavía parece un poco derrochador; todavía estamos generando una nueva matriz cuando la pregunta dejó en claro que la matriz original es mutable, por lo que deberíamos poder eliminarla en su lugar y ahorrar algo de memoria. Algo como esto:
ACTUALIZACIÓN : Yuri Niyazov señaló que mi última respuesta en realidad se ejecuta en O (N 2 ) porque
removeObjectAtIndex:probablemente se ejecuta en tiempo O (N).(Dice "probablemente" porque no sabemos con certeza cómo se implementa; pero una posible implementación es que después de eliminar el objeto en el índice X, el método recorre cada elemento desde el índice X + 1 hasta el último objeto en la matriz , moviéndolos al índice anterior. Si ese es el caso, entonces ese es el rendimiento O (N).)
¿Entonces lo que hay que hacer? Depende de la situación. Si tiene una matriz grande y solo espera una pequeña cantidad de duplicados, la desduplicación en el lugar funcionará bien y le ahorrará tener que construir una matriz duplicada. Si tiene una matriz donde espera muchos duplicados, entonces construir una matriz separada y duplicada es probablemente el mejor enfoque. La conclusión aquí es que la notación big-O solo describe las características de un algoritmo, no le dirá definitivamente cuál es el mejor para cualquier circunstancia.
fuente
Si está apuntando a iOS 5+ (lo que cubre todo el mundo de iOS), mejor uso
NSOrderedSet. Elimina duplicados y conserva el orden de suNSArray.Solo haz
Ahora puede volver a convertirlo en una matriz NSA única
O simplemente use el setSet ordenado porque tiene los mismos métodos como un NSArray
objectAtIndex:,firstObjecty así sucesivamente.Una verificación de membresía
containses aún más rápida en loNSOrderedSetque sería en unNSArrayPara obtener más información, consulte la referencia NSOrderedSet
fuente
Disponible en OS X v10.7 y posterior.
Si está preocupado por el pedido, la forma correcta de hacerlo
Aquí está el código para eliminar valores duplicados de NSArray en orden.
fuente
necesita orden
o no necesita orden
fuente
Aquí eliminé valores de nombre duplicados de mainArray y almacené el resultado en NSMutableArray (listOfUsers)
fuente
Tenga en cuenta que si tiene una matriz ordenada, no necesita verificar con cada otro elemento de la matriz, solo con el último elemento. Esto debería ser mucho más rápido que verificar todos los artículos.
Parece que las
NSOrderedSetrespuestas que también se sugieren requieren mucho menos código, pero siNSOrderedSetpor alguna razón no puede usar una y tiene una matriz ordenada, creo que mi solución sería la más rápida. No estoy seguro de cómo se compara con la velocidad de lasNSOrderedSetsoluciones. También tenga en cuenta que mi código está comprobandoisEqualToString:, por lo que la misma serie de letras no aparecerá más de una veznewArray. No estoy seguro de si lasNSOrderedSetsoluciones eliminarán duplicados según el valor o la ubicación de la memoria.Mi ejemplo supone que
sortedSourceArraycontiene soloNSStrings, soloNSMutableStrings o una mezcla de los dos. Si en susortedSourceArraylugar contiene soloNSNumbers o soloNSDates, puede reemplazarcon
y debería funcionar perfectamente. Si
sortedSourceArraycontiene una mezcla deNSStrings,NSNumbersy / oNSDates, probablemente se bloqueará.fuente
Hay un operador de objetos KVC que ofrece una solución más elegante.
uniquearray = [yourarray valueForKeyPath:@"@distinctUnionOfObjects.self"];Aquí hay una categoría NSArray .fuente
Una forma más simple de probar que no agregará valor duplicado antes de agregar un objeto en la matriz: -
// Supongamos que mutableArray está asignado e inicializado y contiene algún valor
fuente
Eliminar valores duplicados de NSMutableArray en Objective-C
fuente
Aquí está el código para eliminar valores duplicados de NSMutable Array. Funcionará para usted. myArray es su matriz mutable que desea eliminar valores duplicados.
fuente
Usar
Orderedsethará el truco. Esto mantendrá la eliminación de duplicados de la matriz y mantendrá el orden que normalmente no funcionafuente
solo usa este código simple:
dado que nsset no permite valores duplicados y todos los objetos devuelven una matriz
fuente
NSOrderedSetlugar deNSSet.