Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
202 views
in Technique[技术] by (71.8m points)

ios - How to compare 2 NSArrays like NSPredicate Contains

Hello guys here is my problem

NSArray *recipeIngredientsArray = [recipeIngString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]];
NSArray  *haveIngArray = [searchText componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]];

if (haveIngArray.count==recipeIngredientsArray.count) 
{       
//check the contents of 2 arrays 

}

I have 2 arrays that I take from CoreData and if their array length are the same, I will check the content.

In haveIngArray, I will have strings like "rice", "chicken","lettuce".
In recipeIngredientsArray I have strings like "1 spoon of rice","150 gr chicken","1 cup of milk"

Is there anyway to see strings like "rice" and "chicken" is available in recipeIngredientsArray?

I tried to use NSPredicate with contain but it didn't turn out well.

I'm open to suggestions

Thank you

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

recipeIngredientsArray should not contain strings but either dictionaries where one Key/value is @"ingredientName":@"rice" or better objects of class Ingredient with a property name. Than it will become much easier to be queried by predicates.

#import <Foundation/Foundation.h>

@interface RecipeIngredient : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) NSNumber *amount;
@property (nonatomic, copy) NSString *unit;
@end


@implementation RecipeIngredient

-(NSString *)description
{
    return [NSString stringWithFormat:@"%@ %@ %@", _amount, _unit, _name];
}
@end



int main(int argc, const char * argv[])
{

    @autoreleasepool {
        NSArray *recipeIngredientsArray = @[
                                            ({
                                                RecipeIngredient *ing = [[RecipeIngredient alloc] init];
                                                ing.amount = @(1);
                                                ing.name = @"rice";
                                                ing.unit = @"spoon";
                                                ing;
                                            }),
                                            ({
                                                RecipeIngredient *ing = [[RecipeIngredient alloc] init];
                                                ing.amount = @(150);
                                                ing.name = @"chicken";
                                                ing.unit = @"gr";
                                                ing;
                                            }),
                                            ({
                                                RecipeIngredient *ing = [[RecipeIngredient alloc] init];
                                                ing.amount = @(1);
                                                ing.name = @"milk";
                                                ing.unit = @"cup";
                                                ing;
                                            }),
                                            ];

        NSArray *haveIngArray = @[@"rice", @"chicken", @"lettuce"];

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@" self.name  in %@", haveIngArray];

        NSArray *filteredArray = [recipeIngredientsArray filteredArrayUsingPredicate:predicate];

        for (RecipeIngredient *ing in filteredArray) {
            NSLog(@"%@", ing);
        }
    }
    return 0;
}

output:

1 spoon rice
150 gr chicken

Example ho to know what is not in the recipe or not present in the fridge:

NSArray *recipeIngredientsArray = @[
                                    ({
                                        RecipeIngredient *ing = [[RecipeIngredient alloc] init];
                                        ing.amount = @(1);
                                        ing.name = @"rice";
                                        ing.unit = @"spoon";
                                        ing;
                                    }),
                                    ({
                                        RecipeIngredient *ing = [[RecipeIngredient alloc] init];
                                        ing.amount = @(150);
                                        ing.name = @"chicken";
                                        ing.unit = @"gr";
                                        ing;
                                    }),
                                    ({
                                        RecipeIngredient *ing = [[RecipeIngredient alloc] init];
                                        ing.amount = @(1);
                                        ing.name = @"milk";
                                        ing.unit = @"cup";
                                        ing;
                                    }),
                                    ];

NSArray *haveIngArray = @[@"rice", @"chicken", @"lettuce"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"not (self.name  in %@)", haveIngArray];
NSArray *filteredArray = [recipeIngredientsArray filteredArrayUsingPredicate:predicate];
NSArray *filteredIngNames = [filteredArray valueForKey:@"name"];
NSLog(@"in recipe but not in fridge: %@", filteredIngNames);

predicate = [NSPredicate predicateWithFormat:@"not (self  in %@.name)", recipeIngredientsArray];
filteredArray = [haveIngArray filteredArrayUsingPredicate:predicate];
NSLog(@"in fridge but not in recipe: %@", filteredArray);

output:

in recipe but not in fridge: (
    milk
)
in fridge but not in recipe: (
    lettuce
)

How to create custom ingredient objects form the strings you have:

NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];

NSArray *recipe = @[@"1 spoon of rice", @"150 gr chicken", @"1 cup of milk"];
NSMutableArray *recipeIngredientsArray = [@[] mutableCopy];

for (NSString *string in recipe) {
    NSArray *a = [string componentsSeparatedByString:@" "];
    RecipeIngredient *ing = [[RecipeIngredient alloc] init];
    ing.amount = [f numberFromString:a[0]];
    ing.name = [a lastObject];
    ing.unit = [[a subarrayWithRange:NSMakeRange(1, [a count]-2)] componentsJoinedByString:@" "];
    [recipeIngredientsArray addObject:ing];

}

logging recipeIngredientsArray prints

(
    1 spoon of rice,
    150 gr chicken,
    1 cup of milk,
)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.8k users

...