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];
Related
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];
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.
in my project i applied the following code
NSDictionary *dict6 = [self cleanJsonToObject:responseData];
NSLog(#"str : %#",dict6);
diagnosisdict = [[[dict6 objectForKey:#"diagnoses"] objectAtIndex:0] objectForKey:#"DiagnosesHospitals"];
diagnosedictforname = [[[dict6 objectForKey:#"diagnoses"]objectAtIndex:0]objectForKey:#"Diagnoses"];
NSLog(#" for ref id =%# ,name of diagnose=%# data is= %#",refidstr,diagnosedictforname ,diagnosisdict);
and the output in console is comes out as in the form
str : {
diagnoses = (
{
Diagnoses = {
"diagnosis_name" = "TRANSIENT ISCHEMIA";
};
DiagnosesHospitals = {
"charge_amt" = "1300.00";
discharges = "11200.00";
"hospital_id" = 3341;
id = 163080;
"medicare_amt" = "100.00";
"total_amt" = "1100.00";
};
}
);
response = 200;
}
ref id =3341 ,name of diagnose={
"diagnosis_name" = "TRANSIENT ISCHEMIA";
} data is= {
"charge_amt" = "1300.00";
discharges = "11200.00";
"hospital_id" = 3341;
id = 163080;
"medicare_amt" = "100.00";
"total_amt" = "1100.00";
}
now i just want to embed the values of both the Dictionaries into one dictionary
someone please help me to sort out this issue.
Make a mutable copy of the first dictionary:
NSMutableDictionary * mutDic = [dic1 mutableCopy];
and then:
[mutDic addEntriesFromDictionary:dic2];
Try this code:
NSDictionary *dict6 = [self cleanJsonToObject:responseData];
NSLog(#"str : %#",dict6);
NSMutableDictionary *diagnosisdict = [[[dict6 objectForKey:#"diagnoses"] objectAtIndex:0] objectForKey:#"DiagnosesHospitals"];
NSDictionary *diagnosedictforname = [[[dict6 objectForKey:#"diagnoses"]objectAtIndex:0]objectForKey:#"Diagnoses"];
NSArray *keys = [diagnosedictforname allKeys];
for (int i =0; i < keys.count; i++) {
NSString *key = [keys objectAtIndex:i];
[diagnosisdict setValue:[diagnosedictforname valueForKey:key] forKey:key];
}
NSLog(#"your dic -> %#", diagnosisdict);
I need to convert an NSMutableArray to an NSArray from JSON. I loaded the JSON and put it in an NSMutableArray.
NSMutableArray *banner = [[NSMutableArray alloc] init];
banner = [responseObject objectForKey:#"banner"];
This is test for loop:
for(int i = 0; i < [slider count]; i++) {
NSLog(#"%#", [[banner objectAtIndex:i] objectForKey:#"resim"]); }
This is log from the JSON:
(
{
id = 1;
resim = "http://localhost/sample_Files/banner_api/1.jpg";
},
{
id = 2;
resim = "http://localhost/sample_Files/banner_api/2.jpg";
},
{
id = 3;
resim = "http://localhost/sample_Files/banner_api/3.jpg";
}
)
I want to set all of this to be like the below NSArray:
NSArray *allImages = #[#"http://localhost/sample_Files/banner_api/1.jpg",#"http://localhost/sample_Files/banner_api/2.jpg",#"http://localhost/sample_Files/banner_api/3.jpg"];
How can I do this?
NSMutableArray * muArr = [NSMutableArray new];
for(NSDictionary * dict in yourMuArr) {
[muArr addObject:dict[#"resim"]];
}
NSArray * allImages = [NSArray arrayWithArray:muArr];
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.