versiones programación objective lenguaje framework ejemplos objective-c cocoa

objective-c - programación - versiones de objective c



filtrando NSArray en un nuevo NSArray en objetivo-c (8)

Tengo un NSArray y me gustaría crear un nuevo NSArray con objetos de la matriz original que cumplan con ciertos criterios. El criterio es decidido por una función que devuelve un BOOL .

Puedo crear un NSMutableArray , recorrer el conjunto de origen y copiar los objetos que acepta la función de filtro y luego crear una versión inmutable del mismo.

¿Hay una mejor manera?


Basado en una respuesta de Clay Bridges, aquí hay un ejemplo de filtrado usando bloques (cambie su matriz a su nombre de variable de matriz y testFunc al nombre de su función de prueba):

yourArray = [yourArray objectsAtIndexes:[yourArray indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { return [self testFunc:obj]; }]];


Hay muchas maneras de hacerlo, pero con mucho, lo más seguro es utilizar [NSPredicate predicateWithBlock:] :

NSArray *filteredArray = [array filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) { return [object shouldIKeepYou]; // Return YES for each object you want in filteredArray. }]];

Creo que es lo más conciso posible.

Rápido:

Para aquellos que trabajan con NSArray s en Swift, puede preferir esta versión aún más concisa:

nsArray = nsArray.filter { $0.shouldIKeepYou() }

filter es solo un método en Array ( NSArray está puenteado implícitamente con Array de Swift). Se necesita un argumento: un cierre que toma un objeto en la matriz y devuelve un Bool . En su cierre, simplemente devuelva true para cualquier objeto que desee en la matriz filtrada.


Pagar esta biblioteca

https://github.com/BadChoice/Collection

Viene con muchas funciones de matriz fáciles de nunca escribir un bucle de nuevo

Entonces puedes hacer lo siguiente:

NSArray* youngHeroes = [self.heroes filter:^BOOL(Hero *object) { return object.age.intValue < 20; }];

o

NSArray* oldHeroes = [self.heroes reject:^BOOL(Hero *object) { return object.age.intValue < 20; }];



Suponiendo que sus objetos son todos de un tipo similar, puede agregar un método como categoría de su clase base que llama a la función que está utilizando para sus criterios. Luego crea un objeto NSPredicate que se refiera a ese método.

En alguna categoría define tu método que usa tu función

@implementation BaseClass (SomeCategory) - (BOOL)myMethod { return someComparisonFunction(self, whatever); } @end

Entonces, donde sea que estés filtrando:

- (NSArray *)myFilteredObjects { NSPredicate *pred = [NSPredicate predicateWithFormat:@"myMethod = TRUE"]; return [myArray filteredArrayUsingPredicate:pred]; }

Por supuesto, si su función solo se compara con las propiedades accesibles desde dentro de su clase, puede ser más fácil convertir las condiciones de la función en una cadena de predicados.


NSArray y NSMutableArray proporcionan métodos para filtrar los contenidos de la matriz. NSArray proporciona filteredArrayUsingPredicate: que devuelve una nueva matriz que contiene objetos en el receptor que coinciden con el predicado especificado. NSMutableArray agrega filterUsingPredicate: que evalúa el contenido del receptor contra el predicado especificado y deja solo los objetos que coinciden. Estos métodos se ilustran en el siguiente ejemplo.

NSMutableArray *array = [NSMutableArray arrayWithObjects:@"Bill", @"Ben", @"Chris", @"Melissa", nil]; NSPredicate *bPredicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] ''b''"]; NSArray *beginWithB = [array filteredArrayUsingPredicate:bPredicate]; // beginWithB contains { @"Bill", @"Ben" }. NSPredicate *sPredicate = [NSPredicate predicateWithFormat:@"SELF contains[c] ''s''"]; [array filteredArrayUsingPredicate:sPredicate]; // array now contains { @"Chris", @"Melissa" }


NSPredicate es la forma en que nextstep construye la condición para filtrar una colección ( NSArray , NSSet , NSDictionary ).

Por ejemplo, considere dos matrices arr y filteredarr :

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",@"c"]; filteredarr = [NSMutableArray arrayWithArray:[arr filteredArrayUsingPredicate:predicate]];

el filteredarr seguramente tendrá los elementos que contienen el carácter c solo.

para que sea fácil recordar aquellos que tienen poco fondo sql

*--select * from tbl where column1 like ''%a%''--*

1) seleccione * de tbl -> colección

2) column1 como ''% a%'' -> NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",@"c"];

3) selecciona * de tbl donde column1 como ''% a%'' ->

[NSMutableArray arrayWithArray:[arr filteredArrayUsingPredicate:predicate]];

espero que esto ayude


NSArray + Xh

@interface NSArray (X) /** * @return new NSArray with objects, that passing test block */ - (NSArray *)filteredArrayPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate; @end

NSArray + Xm

@implementation NSArray (X) - (NSArray *)filteredArrayPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate { return [self objectsAtIndexes:[self indexesOfObjectsPassingTest:predicate]]; } @end

Puedes descargar esta categoría aquí