Array format:
{
"sku": "NikeL101Black",
"name": "Nike Black shirt -L",
"attribute_set_id": 4,
"price": 30,
"status": 1,
"visibility": 1,
"type_id": "simple",
"created_at": "2015-12-01 23:02:07",
"updated_at": "2015-12-01 23:02:23",
"weight": 2,
"product_links": [],
"options": [],
"tier_prices": [],
"custom_attributes": [
{
"attribute_code": "swatch_image",
"value": "/m/i/miler-uv-mens-t-shirt-black-p7394-6131_zoom_1_1.jpg"
},
{
"attribute_code": "tax_class_id",
"value": "2"
},
{
"attribute_code": "image",
"value": "/m/i/miler-uv-mens-t-shirt-black-p7394-6131_zoom_1_1.jpg"
},
{
"attribute_code": "category_ids",
"value": [
"3"
]
},
{
"attribute_code": "description",
"value": "<p>Cool black nike tshirt</p>"
},
{
"attribute_code": "color",
"value": "7"
},
{
"attribute_code": "required_options",
"value": "0"
},
{
"attribute_code": "size",
"value": "14"
},
{
"attribute_code": "has_options",
"value": "0"
},
{
"attribute_code": "vendor",
"value": "Paxcel Cloth House"
},
{
"attribute_code": "small_image",
"value": "/m/i/miler-uv-mens-t-shirt-black-p7394-6131_zoom_1_1.jpg"
},
{
"attribute_code": "thumbnail",
"value": "/m/i/miler-uv-mens-t-shirt-black-p7394-6131_zoom_1_1.jpg"
},
{
"attribute_code": "url_key",
"value": "nike-red-shirt-s-7"
},
{
"attribute_code": "meta_title",
"value": "Nike Red shirt -S"
},
{
"attribute_code": "meta_keyword",
"value": "Nike Red shirt -S"
},
{
"attribute_code": "meta_description",
"value": "Nike Red shirt -S <p>Cool red noke tshirt</p>"
},
{
"attribute_code": "options_container",
"value": "container2"
}
]
},
How to filter an array of above type dictionaries by (attribute_code = color and value = 7) AND (attribute_code = size and value = 12)
I tried with a compound predicate:
NSPredicate *filterChildrenBySize = [NSPredicate predicateWithFormat:#"ANY custom_attributes.attribute_code == size AND custom_attributes.value.integerValue == %#", [[attributes objectForKey:#"sizeInfo"] objectForKey:kAttributeCodeSize]];
Predicate looks like this --> ANY custom_attributes.attribute_code == color AND custom_attributes.value.integerValue == 4
You have to do like this. Check the NSLog of filterArray.
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];
NSLog(#"OUTPUT DATA: %#" ,jsonDict);
NSArray *arrayList = [jsonDict objectForKey:#"custom_attributes"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self.attribute_code == 'color' AND self.value == '7'"];
NSArray *filterArray = [arrayList filteredArrayUsingPredicate:predicate];
NSLog(#"FILTERED DATA: %#" ,filterArray);
Here 'jsonString' is the String what you provided. I just did the NSJSONSerialization to convert the Stirng into NSDictionary.
You have to merge both filters with OR instead of AND. It will never compare with AND in your case and will return 0 objects as filteredArray
Here is a compound predicate for your custom_attributes array.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(attribute_code ==[c] 'color' AND value == '7') OR (attribute_code ==[c] 'size' AND value == '12')"];
// Assuming that you have parsed you custom_attributes object to customAtrributes
NSArray *filteredArray = [customAtrributes filteredArrayUsingPredicate:predicate];
Try to use ANY for that.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"custom_attributes.value == %d", 7];
NSArray *filterArray = [yourArray filteredArrayUsingPredicate:predicate];
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:#"custom_attributes.attribute_code CONTAINS[c] %#", "color"];
NSArray *filterArray1 = [filterArray filteredArrayUsingPredicate:predicate1];
Related
Below is a part of my JSON response where 'results' is an array of dictionaries :
{
"results": [
{
"id": 6,
"genre_name": "Action",
"cover_image": "http://54.254.204.81/images/Action.png"
},
{
"id": 5,
"genre_name": "Adventure",
"cover_image": "http://54.254.204.81/images/Adventure.png"
},
{
"id": 4,
"genre_name": "Romance",
"cover_image": "http://54.254.204.81/images/Romance.png"
},
{
"id": 3,
"genre_name": "Sci-Fci",
"cover_image": "http://54.254.204.81/images/Sci-Fi.png"
},
{
"id": 1,
"genre_name": "Guide",
"cover_image": "http://54.254.204.81/images/Adventure_XHLbNfN.png"
},
{
"id": 2,
"genre_name": "Horror",
"cover_image": "http://54.254.204.81/images/Phineas-and-Ferb-Christmas-Wallpaper.jpg"
},
{
"id": 7,
"genre_name": "Emotional",
"cover_image": "http://54.254.204.81/images/a0fea991287cf41b6b9c4aa16196517f.jpg"
},
{
"id": 8,
"genre_name": "abcd",
"cover_image": "http://54.254.204.81/images/logo_text_S0KyzUW.png"
}
]
}
Now I have another JSON response where 'genres' is an array which contains objects which are subset of 'results' array objects with key 'id'.
{
"genres": [
3,
1
]
}
Now, is it possible for me to split 'results' into two arrays 'results1' and 'results2' like:
{
"results1": [
{
"id": 6,
"genre_name": "Action",
"cover_image": "http://54.254.204.81/images/Action.png"
},
{
"id": 5,
"genre_name": "Adventure",
"cover_image": "http://54.254.204.81/images/Adventure.png"
},
{
"id": 4,
"genre_name": "Romance",
"cover_image": "http://54.254.204.81/images/Romance.png"
},
{
"id": 2,
"genre_name": "Horror",
"cover_image": "http://54.254.204.81/images/Phineas-and-Ferb-Christmas-Wallpaper.jpg"
},
{
"id": 7,
"genre_name": "Emotional",
"cover_image": "http://54.254.204.81/images/a0fea991287cf41b6b9c4aa16196517f.jpg"
},
{
"id": 8,
"genre_name": "abcd",
"cover_image": "http://54.254.204.81/images/logo_text_S0KyzUW.png"
}
]
}
and
{
"results2": [
{
"id": 3,
"genre_name": "Sci-Fci",
"cover_image": "http://54.254.204.81/images/Sci-Fi.png"
},
{
"id": 1,
"genre_name": "Guide",
"cover_image": "http://54.254.204.81/images/Adventure_XHLbNfN.png"
}
]
}
For that you need to use NSPredicate with IN and NOT like this way.
First create resultArray and genresArray from your two JSON responses.
NSArray *resultArray = [firstJSONResponse objectForKey:#"results"];
NSArray *genresArray = [secondJSONResponse objectForKey:#"genres"];
Now filter your resultArray using NSPredicate to get your result.
For Result1
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"NOT (id IN %#)",genresArray];
NSArray *firstSplitArray = [resultArray filteredArrayUsingPredicate:predicate];
NSLog(#"%#",firstSplitArray);
For Result2
predicate = [NSPredicate predicateWithFormat:#"id IN %#",genresArray];
NSArray *secondSplitArray = [resultArray filteredArrayUsingPredicate:predicate];
NSLog(#"%#",secondSplitArray);
Do like following way:
NSMutableArray * genresArray = [NSMutableArray new];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"NOT (id IN %#)", genresArray];
NSArray *filterArray = [Yourarray filteredArrayUsingPredicate:predicate];
NSLog(#"filter: %#",filterArray);
Try This One For Above Scenario:
NSDictionary *yourJson;
NSMutableArray *array1 = [[yourJson valueForKey:#"results"] mutableCopy];
NSMutableArray *array2 = [[yourJson valueForKey:#"results2"] mutableCopy];
for(int i =0 ; i<array2.count ; i++)
{
NSString *objectFromarray2 = [array2 objectAtIndex:i];
for(int j =0 ; j<array1.count ; j++)
{
NSDictionary *objectFromarray1 = [array2 objectAtIndex:i];
if([[objectFromarray1 valueForKey:#"id"] isEqualToString:objectFromarray2])
{
[array2 removeObjectAtIndex:i];
[array2 insertObject:objectFromarray1 atIndex:i];
[array1 removeObject:objectFromarray1];
}
}
}
Yes, you can do that using NSPredicate, but for that you first have to store all your dictionary objects into one NSArray or NSMutableArray whatever suits to your requirement.
Do like:
NSString *search1 = #"3";
NSString *search2 = #"1";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(ANY SELF == %#) OR (ANY SELF == %#)", search1,search2];
NSArray *filtered = [Yourarray filteredArrayUsingPredicate:predicate];
one way to do in Swift - 3 using filter and map
let resultArray = results["results"]!
let genArray = genres["genres"]!
var result1Array : [[String:Any]] = resultArray
var result2Array : [[String:Any]] = []
for gen in genArray {
if let elm = resultArray.filter({ $0["id"] as! Int == gen }).first {
result2Array.append(elm)
result1Array = result1Array.filter({ $0["id"] as! Int != elm["id"] as! Int })
}
}
print(["result2":result2Array])
print("\n")
print(["result1":result1Array])
So I have an NSDictionary that has a variety of data within it. When printed to the log, it prints like this:
[{"user_id":3016817,"grade":"A","percent":"93","grading_periods":[{"assignments":[{"points":100.0,"grade":"A","score":95.0,"percent":"93","comment":null,"id":3268180},{"points":100.0,"grade":"A","score":90.0,"percent":"93","comment":null,"id":3268181}],"grade":"A","percent":"93","name":"Default"}]},{"user_id":3016818,"grade":"A","percent":"94","grading_periods":[{"assignments":[{"points":100.0,"grade":"A","score":92.0,"percent":"94","comment":null,"id":3268180},{"points":100.0,"grade":"A","score":95.0,"percent":"94","comment":null,"id":3268181}],"grade":"A","percent":"94","name":"Default"}]}]
If I use a formatter online, its a lot more readable and looks something like this:
[
{
"user_id": 3016817,
"grade": "A",
"percent": "93",
"grading_periods": [
{
"assignments": [
{
"points": 100,
"grade": "A",
"score": 95,
"percent": "93",
"comment": null,
"id": 3268180
},
{
"points": 100,
"grade": "A",
"score": 90,
"percent": "93",
"comment": null,
"id": 3268181
}
],
"grade": "A",
"percent": "93",
"name": "Default"
}
]
},
{
"user_id": 3016818,
"grade": "A",
"percent": "94",
"grading_periods": [
{
"assignments": [
{
"points": 100,
"grade": "A",
"score": 92,
"percent": "94",
"comment": null,
"id": 3268180
},
{
"points": 100,
"grade": "A",
"score": 95,
"percent": "94",
"comment": null,
"id": 3268181
}
],
"grade": "A",
"percent": "94",
"name": "Default"
}
]
}
]
My question would be how would I access the value of grade or score for a specific user_id using this dictionary?
Your string represents a NSArray, not a NSDictionary. And it's a JSON string, so you can parse it using NSJSONSerialization:
NSString *jsonString = #"..." // your string here
// Create array from json string
NSArray *jsonArray = [NSJSONSerialization
JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding]
options:NSJSONReadingMutableContainers
error:Nil];
// Loop to find your user_id
// Because each child of this array is a dictionary
for (NSDictionary *dic in jsonArray) {
if ([dic[#"user_id"] isEqual:#3016817]) { // user_id field is number
// Access what you want
NSString *grade = dic[#"grade"];
// For "score" you must go deeper
// Just remember, [] is array and {} is dictionary
}
}
A simple way to do this would be
for (NSDictionary* d in theArray) {
if ([d[#"user_id"] isEqualToString: u]) {
// do something
}
}
And matt is right, it is an array of dictionaries, no matter what type you declared to be.
You can use below class method of NSJsonSerialization class to create NSArray which will contain all the dictionaries.
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
Once you get the array of dictionaries from JSON, you can do following:
NSArray *filteredjsonArr = [jsonArr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"user_id == %#", #"3016818"]];
NSDictionary *dict = [filtered firstObject];
if (dict != nil) {
NSString *grade = [dict objectForKey:#"grade"];
NSArray *gradingPeriods = [dict objectForKey:#"grading_periods"];
}
To access score and grade for specific assignments, you'll need to drill down further into gradingPeriods array.
My response is like;
{
Writers : [
{
"name": "Mad Decent Block Party NYC",
"artist": [
{
"artist_name": "Dillon Francis",
"name": "Dillon Francis",
"Books" : ["Book1", "Book2", "Book3"]
},
{
"artist_name": "Major Lazer",
"name": "Major Lazer",
"Books" : ["Book4", "Book5", "Book6"]
},
{
"artist_name": "Flosstradamus ",
"name": "Flosstradamus",
"Books" : ["Book7", "Book8", "Book9"]
}
],
},{
"name": "Kaskade Atmosphere Tour NYC",
"artist": [
{
"artist_name": "Ryan Raddon",
"name": "Kaskade",
"Books" : ["Book1", "Book2", "Book3"]
}
],
},
]
}
I want to search through Books array on each dict of artist array. When text matches result should be total dict object from writers array along with matched books objects.
For example my search is for Book1, result should look like,
Writers : [
{
"artist": [
{
"artist_name": "Dillon Francis",
"name": "Dillon Francis",
"Books" : ["Book1", "Book2", "Book3"]
},
],
"name": "Mad Decent Block Party NYC",
},{
"artist": [
{
"artist_name": "Ryan Raddon",
"name": "Kaskade",
"Books" : ["Book1", "Book2", "Book3"]
}
],
"name": "Kaskade Atmosphere Tour NYC",
},
]
You just need to write two lines of code for this. You form a predicate, and filter the writers array with the predicate.
You can use the keypaths in the predicate, and check if the book array contains the given book name.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY artist.Books contains[cd] 'Book1'"];
NSArray *arr = [responseDict[#"Writers"] filteredArrayUsingPredicate:predicate];
This should work.
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"ANY artist.Books CONTAINS[cd] %#", #"Book1"];
NSArray *temp = [[sampleDic objectForKey:#"Writers"] filteredArrayUsingPredicate:predicate];
This is the first thing i thought, but looking at your dictionary structure, i think this will not work for you. But if you want to recreate your structure to:
#{
#"Writers":
#[
#{
#"name" :#"name1",
#"artist" :#[ #"Books":[...] ]
},
#{
#"name" :#"name2",
#"artist" :#[ #"Books":[...] ]
},
#{
#"name" :#"name3",
#"artist" :#[ #"Books":[...] ]
}
]
};
it will.
This is not the best solution but i think this will work for you..
Sample input:
NSDictionary *sampleDic = #{
#"Writers":
#[
#{
#"name" :#"Mad Decent Block Party NYC",
#"artist" :#[
#{
#"artist_name":#"Dillon Francis",
#"name": #"Dillon Francis",
#"Books" : #[#"Book1", #"Book2", #"Book3"]
},
#{
#"artist_name":#"Major Lazer",
#"name": #"Major Lazer",
#"Books" : #[#"Book4", #"Book5", #"Book6"]
},
#{
#"artist_name":#"Flosstradamus",
#"name": #"Flosstradamus",
#"Books" : #[#"Book7", #"Book8", #"Book9"]
}
]
},
#{
#"name" :#"Kaskade Atmosphere Tour NYC",
#"artist" :#[
#{
#"artist_name":#"Ryan Raddon",
#"name": #"Kaskade",
#"Books" : #[#"Book1", #"Book2", #"Book3"]
}
]
}
]
};
And the filtering:
- (NSDictionary *)filterDictionary:(NSDictionary *)sampleDic withBookName:(NSString *)bookName
{
NSMutableArray *compiledArr = [[NSMutableArray alloc] init];
for (NSDictionary *itemDic in [sampleDic objectForKey:#"Writers"])
{
NSArray *itemDicKeys = [itemDic allKeys];
for (int i = 0; i < itemDicKeys.count; i++)
{
if ([itemDicKeys[i] isEqual:#"artist"])
{
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"SELF['Books'] CONTAINS[cd] %#", bookName];
NSArray *tempResult = [[itemDic objectForKey:itemDicKeys[i]] filteredArrayUsingPredicate:predicate];
NSDictionary *result = #{#"name": [itemDic objectForKey:#"name"],
#"artist": tempResult};
[compiledArr addObject:result];
}
}
}
NSDictionary *resultDic = #{#"Writer":compiledArr};
return resultDic;
}
Using it like: NSLog(#"tempResult :%#", [self filterDictionary:sampleDic withBookName:#"Book1"]);
Result is:
I have following JSON response which has been stored in NSMutableDictonary. I want to addition of all the price of special_item.
{
"order_id": "1",
"order_name": "xyz",
"order_item": [
{
"item_id": "1",
"item_name": "myone",
"special_item": [
{
"s_item_id": "1",
"price": "10"
},
{
"s_item_id": "2",
"price": "100"
}
]
},
{
"item_id": "2",
"item_name": "mytwo",
"special_item": [
{
"s_item_id": "11",
"price": "15"
},
{
"s_item_id": "22",
"price": "110"
}
]
}
]
}
Is it possible to do addition of all the price using NSPredicate ? or How can I get array of all the price values using NSPredicate?(e.g : [#10,#100,#15,#110])
Thank you!
It is so simple
you can try below code
NSArray *arr = [dix valueForKeyPath:#"order_item.special_item.price"];
long total = 0;
for (id price in arr) {
if ([price isKindOfClass:[NSArray class]]) {
total += [[price valueForKeyPath:#"#sum.self"] longValue];
}
else {
total += [price longValue];
}
}
NSInteger *total=0;
NSArray *arr=[NSDictionary objectForKey=#"order_item"];
for(NSDictionary *dic in arr){
NSArray *array=[dic objectForKey=#"special_item"];
for(NSDictionary *d in array){
total=total+[[d objectForKey=#"price"] intValue];
}
}
NSLog("Total:- %d",total);
I want to filter below array of disc, here is my code but app is crashing
NSPredicate *pred = [NSPredicate predicateWithFormat:#"Id contains[c] %# ", string];
NSArray *result = [array filteredArrayUsingPredicate:pred];
return result;
[{
"Id": 1,
"VoteCode": "1"
}, {
"Id": 2,
"VoteCode": "1"
}, {
"Id": 3,
"VoteCode": "1"
}, {
"Id": 8,
"VoteCode": "12345"
}, {
"Id": 9,
"VoteCode": "103"
}, {
"Id": 10,
"VoteCode": "12345"
}]
Your predicate format is wrong. The CONTAINS operator is for string comparison (see the predicate programming guide), but your "Id" key in each dictionary is not a string, it's a number.
You can either store your Id's as strings, or use a different predicate; for example:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"%K ==[cd] %# ", #"Id", #1];