Filter NSMutableArray based on dictionary key - ios

I have array with multiple dictionarys. which contains different keys . here i have goalType each goal contains number of records i want to filter the records based on goalType . please check the format below.
Array==>( {
goalType = 1;
languagetype = 1;
soundid = 19;
status = 1;
},
{
goalType = 1;
languagetype = 1;
soundid = 20;
status = 1;
},
{
goalType = 2;
languagetype = 1;
soundid = 21;
status = 1;
},
{
goalType = 2;
languagetype = 1;
soundid = 22;
status = 1;
},
{
goalType = 2;
languagetype = 1;
soundid = 23;
status = 1;
},
)
i have wrote the below code but filtered array getting empty
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"goalType == %# && languagetype == %d && status == 1 && soundid <= 3884",
[NSNumber numberWithInt:goalType.integerValue],languageid];
[dataSource predicate];

why not use
NSArray's filteredArrayUsingPredicate:
Evaluates a given predicate against each object in the receiving array and returns a new array containing the objects for which the predicate returns true.
I don't know of a
[NSArray predicate]
selector.I'm surprised that your not getting NoMethodFound exception.

NSDictionary *theDict = #{#"goalType":#(1),#"languagetype":#(1),#"soundid":#(19),#"status":#(1)};
NSDictionary *theDict1 = #{#"goalType":#(1),#"languagetype":#(1),#"soundid":#(20),#"status":#(1)};
NSDictionary *theDict2 = #{#"goalType":#(2),#"languagetype":#(1),#"soundid":#(21),#"status":#(1)};
NSDictionary *theDict3 = #{#"goalType":#(2),#"languagetype":#(1),#"soundid":#(23),#"status":#(1)};
NSMutableArray *testArray = [NSMutableArray array];
[testArray addObject:theDict];
[testArray addObject:theDict1];
[testArray addObject:theDict2];
[testArray addObject:theDict3];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"goalType == %# && languagetype == %# && status = 1 && soundid <= 3884", [NSNumber numberWithInt:1],[NSNumber numberWithInt:1]];
NSArray *filteredArray = [testArray filteredArrayUsingPredicate:predicate];
NSLog(#"%#",filteredArray);
This is the code works.

Related

Searching in Dictionary of arrays in Objective C [duplicate]

i have a NSDictionary like:
{
"2017-05-02" = (
{
"always_valid" = 0;
date = "2017-05-02";
from = "12:00";
to = "13:00";
},
{
"always_valid" = 0;
date = "2017-05-02";
from = "12:00";
to = "12:00";
},
{
"always_valid" = 0;
date = "2017-05-02";
from = "14:00";
"hourly_rate" = 12;
to = "15:00";
}
);
"2017-05-03" = (
{
"always_valid" = 0;
date = "2017-05-03";
from = "12:00";
to = "13:00";
}
);
"2017-05-18" = (
{
"always_valid" = 1;
date = "2017-05-18";
from = "12:00";
to = "12:00";
}
);
}
i'm trying to apply
NSPredicate *filter = [NSPredicate predicateWithFormat:#"always_valid = \"1\""];
NSArray *alwaysvalid = [[dic allValues] filteredArrayUsingPredicate:filter];
it use to work when i had structure something like
array > dictionary
but now it's like
array > array > dictionary
by doing [dic allValues] for array.
any help what should i apply to keep it fast.
What you need to do is need enumerate your dictionary and create new filtered Dictionary.
NSMutableDictionary *filterDic = [[NSMutableDictionary alloc] init];
NSPredicate *filter = [NSPredicate predicateWithFormat:#"always_valid = 1"];
[dict enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSArray* obj, BOOL *stop) {
NSArray *filterArray = [obj filteredArrayUsingPredicate:filter];
if (filterArray.count > 0) {
filterDic[key] = filterArray;
}
}];
Try this :
NSArray *array = [NSArray arrayWithObject:dict]; // you can also do same for Name key...
NSArray *alwaysvalid = [array filteredArrayUsingPredicate:filter];

Remove " " from key string in a NSMutableDictionary

Here's my dictionary:
Birthdate = "01-01-0001";
CareerField = 3;
Gender = 2;
"Interests[0].UserProfileId" = 19594;
"Interests[0].UserSurveyId" = 1;
SocialStatus = 2;
Studies = 3;
But I want the Interests key to be without "".Like that:
Birthdate = "01-01-0001";
CareerField = 3;
Gender = 2;
Interests[0].UserProfileId = 19594;
Interests[0].UserSurveyId = 1;
SocialStatus = 2;
Studies = 3;
UPDATE:
Interests i must send them like array.
[dict setObject:self.birthdayDate forKey:#"Birthdate"]
[dict setObject:#(self.occupationPickerRow + 1) forKey:#"CareerField"];
for (int i = 0; i < [interestsArray count]; i++) {
NSString *stringSurveyId = [NSString stringWithFormat:#"%#%d%#", #"Interests[", indexCount, #"].UserSurveyId"];
NSString *stringUserProfileId = [NSString stringWithFormat:#"%#%d%#", #"Interests[", indexCount, #"].UserProfileId"];
[dict setObject:[interestsArray objectAtIndex:i] forKey:stringSurveyId];
[dict setObject:#([[[MZEngine sharedInstance] currentUserModel] userId]) forKey:stringUserProfileId];
indexCount++;
}

NSDictionary Getting Repeated values

I know this may be a repeated question but I googled a lot but not able to find a suitable answer for me.
I have a NSMutableArray which has two NSDictionary with Keys and values which I need to populated on a UITableView. I have retrieved the value of the dictionary which I'm going populate using
NSMutableArray *mutArray = [responseArray valueForKey:#"Table"];
And I did like
NSMutableSet *names = [NSMutableSet set];
NSMutableArray *mutArray1 = [[NSMutableArray alloc] init];
for (id obj in mutArray) {
NSString *destinationName = [obj valueForKey:#"AssetClassName"];
if (![names containsObject:destinationName]) {
[mutArray1 addObject:destinationName];
[names addObject:destinationName];
}
}
Because the value AssetClassName is repeated. Now I have three values in mutArray1 which I need to show as UITableView section. Under AssetClassName I have Some data which determines the row in that section.
For retrieving that data I'm doing like
for (int i = 0; i < [mutArray1 count]; i++) {
NSMutableDictionary *a = [[NSMutableDictionary alloc] init];
NSMutableDictionary *b = [[NSMutableDictionary alloc] init];
for (NSDictionary *dict in mutArray) {
if ([[mutArray1 objectAtIndex:i] isEqualToString:[dict valueForKey:#"AssetClassName"]]) {
[a setObject:[dict objectForKey: #"SubAssetClassName"] forKey:#"Investment Categories"];
[a setObject:[dict valueForKey:#"Amount"] forKey:#"Amount (EUR)"];
[a setObject:[dict valueForKey:#"AllocationPercentage"] forKey:#"%"];
[a setObject:[dict valueForKey:#"ModelAllocationPercentage"] forKey:#"ModelAllocationPercentage"];
[b setObject:a forKey:[dict valueForKey:#"SubAssetClassName"]];
[mutdict setObject:b forKey:[dict valueForKey:#"AssetClassName"]];
}
}
}
mutdict is a NSMutableDictionary declared globally and is instantiate in viewdidLoad
mutdict = [[NSMutableDictionary alloc] init];
The values are inserted into mutdict as I needed. Each SubAssetClassName is added into AssetclassName accordingly.
But my problem is in my final dictionary i.e mutdict the values for SubAssetClassName is repeated.
Can anybody tell how to solve this.
My console
"AssetClassName" = {
"SubAssetClass" = {
"%" = 0;
"Amount (EUR)" = 0;
"Investment Categories" = "HIGH YIELD BONDS";
"ModelAllocationPercentage" = 22;
};
"SubAssetClass" = {
"%" = 0;
"Amount (EUR)" = 0;
"Investment Categories" = "HIGH YIELD BONDS";
"ModelAllocationPercentage" = 22;
};
"SubAssetClass" = {
"%" = 0;
"Amount (EUR)" = 0;
"Investment Categories" = "HIGH YIELD BONDS";
"ModelAllocationPercentage" = 22;
};
};
"AssetClassName" = {
"SubAssetClass" = {
"%" = 0;
"Amount (EUR)" = 0;
"Investment Categories" = "EMERGING MARKETS EQUITIES";
"ModelAllocationPercentage" = 10;
};
};
"AssetClassName" = {
"SubAssetClass" = {
"%" = 0;
"Amount (EUR)" = 0;
"Investment Categories" = "STRUCTURED PRODUCTS";
"ModelAllocationPercentage" = 10;
};
"SubAssetClass" = {
"%" = 0;
"Amount (EUR)" = 0;
"Investment Categories" = "STRUCTURED PRODUCTS";
"ModelAllocationPercentage" = 10;
};
"SubAssetClass" = {
"%" = 0;
"Amount (EUR)" = 0;
"Investment Categories" = "STRUCTURED PRODUCTS";
"ModelAllocationPercentage" = 10;
};
};
}
Here I can see that all SubAssetClass values are same for each section but actually its not.
How can I solve this.
You need to create a new instance of your mutable dictionary inside the loop. Right now you create one instance and update it over and over. This results in one dictionary being added over and over.
Change you code as follows:
for (NSInteger i = 0; i < [mutArray1 count]; i++) {
NSMutableDictionary *b = [[NSMutableDictionary alloc] init];
for (NSDictionary *dict in mutArray) {
if ([[mutArray1 objectAtIndex:i] isEqualToString:[dict valueForKey:#"AssetClassName"]]) {
NSMutableDictionary *a = [[NSMutableDictionary alloc] init];
[a setObject:[dict objectForKey: #"SubAssetClassName"] forKey:#"Investment Categories"];
[a setObject:[dict valueForKey:#"Amount"] forKey:#"Amount (EUR)"];
[a setObject:[dict valueForKey:#"AllocationPercentage"] forKey:#"%"];
[a setObject:[dict valueForKey:#"ModelAllocationPercentage"] forKey:#"ModelAllocationPercentage"];
[b setObject:a forKey:[dict valueForKey:#"SubAssetClassName"]];
[mutdict setObject:b forKey:[dict valueForKey:#"AssetClassName"]];
}
}
}
Also, in most cases you should not be using valueForKey:. Use objectForKey: unless you have a clear and specific need to use key-value coding instead of simply getting an object from the dictionary for a given key.

NSPredicate for array of Dictionaries generating null array

I'm a Begginer in Objective-C coding and I need some help on NSPredicates.
I need to filter (by id_especie) an Array of Dictionaries that I've parsed from a Json file and retrieve the data to another array. Unfortunate all I got is a null array;
That's my Array of Dictionaries (id_especie mean species_id and id_raca mean breed_id) :
{
"id_especie" = 1;
"id_raca" = 1;
raca = Afghanhound;
},
{
"id_especie" = 1;
"id_raca" = 2;
raca = "Airedale Terrier";
},
{
"id_especie" = 1;
"id_raca" = 3;
raca = Akita;
},...,
{
"id_especie" = 2;
"id_raca" = 47;
raca = "N/I";
},
{
"id_especie" = 2;
"id_raca" = 48;
raca = Siames;
},
{
"id_especie" = 3;
"id_raca" = 49;
raca = Periquito;
},
{
"id_especie" = 4;
"id_raca" = 50;
raca = Cobra;
},
{
"id_especie" = 4;
"id_raca" = 51;
raca = Lagarto;
},
{
"id_especie" = 5;
"id_raca" = 52;
raca = "Furao";
},
{
"id_especie" = 5;
"id_raca" = 53;
raca = Hamster;
},
{
"id_especie" = 6;
"id_raca" = 54;
raca = Outros;
}
And this is my code:
.h
#property (nonatomic, strong) NSMutableArray *arrayBreedAndSpecies;
#property (nonatomic, strong) NSArray *filteredArray; //edited
.m
NSError *errorLoad = nil;
NSURL *jsonUrl = [[NSURL alloc]initWithString:#"http://marcosdegni.com.br/petsistema/teste/raca.php"];
NSString *jsonString = [NSString stringWithContentsOfURL:jsonUrl encoding:NSUTF8StringEncoding error:&errorLoad];
if (!errorLoad) {
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
self.arrayBreedAndSpecies = [[NSMutableArray alloc] initWithArray:jsonArray];
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%# = %#",#"id_especie", #"2"];
[self.filteredArray setArray: [self.arrayBreedAndSpecies filteredArrayUsingPredicate:predicate]];
NSLog(#"Filter: %#", self.filteredArray);
OK I've noticed a few errors with your NSPredicate code:
1) A dynamic key path in a predicate should be %K not %#.
2) To check if a number value is equal to another you need to use == not just =
Therefore the last section of code should be:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K == %i",#"id_especie", 2];
self.filteredArray = [NSArray arrayWithArray:[self.arrayBreedAndSpecies filteredArrayUsingPredicate:predicate]];
NSLog(#"Filter: %#", self.filteredArray);
I'm assuming here that the id_especie property is a number value. If it is a string value you could use the predicate: [NSPredicate predicateWithFormat:#"%K MATCHES[cd] %#", #"id_especie", #"2"];
Hope this helps
just a guess here, because there isn't a working code example here:
[self.filteredArray setArray: [self.arrayBreedAndSpecies filteredArrayUsingPredicate:predicate]];
if self.filteredArray is nil, that line will do nothing... I bet you really mean:
self.filteredArray = [self.arrayBreedAndSpecies filteredArrayUsingPredicate:predicate];

ios NSPredicate to find nearest value in NSDictionary

I have an array of dictionaries like this:
(
{ key = 1, value = 40},
{ key = 4, value = 50},
{ key = 8, value = 60}
}
These are like this,
for >=1 item cost is 40,
for >=4 item cost is 50 and like wise.
I would like to get the value for 5, which in this case is 50.
The piece of code I have tried is:
NSMutableArray *wallpaperPriceArray = [[NSMutableArray alloc]init]; // Assuming this has all the dictionary values
float wallpaperPriceValue = 0;
int itemNumber = 0;
for (int i = 0; i<wallpaperPriceArray.count; i++) {
int check = 0;
if(itemNumber >= [[wallpaperPriceArray objectAtIndex:i] intValue])
{
wallpaperPriceValue = [[[wallpaperPriceArray objectAtIndex:i] objectForKey:#"value"] floatValue];
check++;
}
if(i + 1 <= wallpaperPriceArray.count)
{
if(itemNumber >= [[wallpaperPriceArray objectAtIndex:i+1] intValue] && itemNumber < [[wallpaperPriceArray objectAtIndex:i+1] intValue])
{
wallpaperPriceValue = [[[wallpaperPriceArray objectAtIndex:i+1] objectForKey:#"value"] floatValue];
check++;
if(check == 2)
{
break ;
}
}
}
if(i + 2 <= wallpaperPriceArray.count)
{
if(itemNumber >= [[wallpaperPriceArray objectAtIndex:i+2] intValue] && itemNumber < [[wallpaperPriceArray objectAtIndex:i+2] intValue])
{
wallpaperPriceValue = [[[wallpaperPriceArray objectAtIndex:i+2] objectForKey:#"value"] floatValue];
check++;
if(check == 2)
{
break ;
}
}
}
I Don't think the predicate is the right thing, Better would be to enumerate the objects here is some sample code:
NSArray *array = #[
#{ #"key" : #(1), #"value" : #(40)},
#{ #"key" : #(4), #"value" : #(50)},
#{ #"key" : #(8), #"value" : #(60)}
];
NSInteger searchedValue = 5; // <---
__block NSDictionary *closestDict = nil;
__block NSInteger closestValue = 0;
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSDictionary *dict = obj;
NSInteger key = [dict[#"key"] integerValue];
// Check if we got better result
if(closestDict == nil || (key > closestValue && key <= searchedValue)){
closestDict = dict;
closestValue = key;
if(key == searchedValue) { *stop = YES; }
}
}];
NSLog(#"value %#", closestDict);
I would suggest in addition to above answer to use the spline method to get the value needed, this is in the link
https://github.com/soffes/SAMCubicSpline
Using this library would solve the question as follows:
NSArray *array = #[
#{ #"key" : #(1), #"value" : #(40)},
#{ #"key" : #(4), #"value" : #(50)},
#{ #"key" : #(8), #"value" : #(60)}];
SAMCubicSpline *spline = [[SAMCubicSpline alloc] initWithPoints:#[
[NSValue valueWithCGPoint:CGPointMake(1.0f, 40.0f)],
[NSValue valueWithCGPoint:CGPointMake(4.0f, 50f)],
[NSValue valueWithCGPoint:CGPointMake(8.0f, 60.0f)],
]];
then you can obtain any value by this
CGFloat y = [spline interpolate:x];

Resources