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])
Related
I have a JSON array with multiple object and I don't know how do I grab the "url" tag as an NSArray or a NSDictionary and show that image url in CollectionView. I can't change the JSON data format.How should I do this?
Here is what the JSON response looks like:
{
"error": false,
"data": [
{
"albumid": 2,
"albumtitle": "Album 2",
"images": [
{
"image": "Img2.jpeg",
"imageid": 11
},
{
"image": "vr4.jpg",
"imageid": 4
},
{
"image": "3purple b-ball.jpg",
"imageid": 3
}
]
},
{
"albumid": 3,
"albumtitle": "Album 3",
"images": [
{
"image": "vr2.jpg",
"imageid": 6
},
{
"image": "vr1.jpg",
"imageid": 5
}
]
},
{
"albumid": 4,
"albumtitle": "Album 4",
"images": [
{
"image": "vr1.jpg",
"imageid": 8
}
]
},
{
"albumid": 12,
"albumtitle": "My Album",
"images": [
{
"image": "img3.jpeg",
"imageid": 64
},
{
"image": "img4.jpeg",
"imageid": 63
},
{
"image": "img5.jpeg",
"imageid": 62
}
]
},
{
"albumid": 13,
"albumtitle": "Demo Album",
"images": [
{
"image": "img6.jpeg",
"imageid": 67
},
{
"image": "img7.jpeg",
"imageid": 66
},
{
"image": "img11.jpeg",
"imageid": 65
}
]
}
]
}
Try something like this (data is the NSData object you get from your webserver):
NSError *jsonError = nil;
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError];
if(!jsonError){
NSArray *dataArray = [jsonData objectForKey:#"data"];
NSDictionary *albumDict = [dataArray objectAtIndex:0];
NSArray *imagesArray = [albumDict objectForKey:#"images"];
NSDictionary *imageDict = [imagesArray objectAtIndex:0];
NSString *imageURL = [imageDict objectForKey: #"image"];
}
Of course, you have to use loops for the array elements, this example is only with element 0. Some more checks if a field exists etc. would be good.
You can create a model to hold the image id and url. You add an array of these image objects in the main model (Album). In Swift, your models might look like this
class Album {
var albumId = ""
var albumTitle = ""
var albumImages = [AlbumImage]()
}
class AlbumImage {
var imageId = ""
var imageUrl = ""
}
Hope this helps!
Use this code after downloaded the json file.
NSDictionary *rootDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSArray *rootArray = rootDict[#"data"];
NSDictionary *subDict;
NSArray *subArray;
NSDictionary *tempDict;
for (int i=0; i<rootArray.count; i++) {
subDict = rootArray[i];
subArray = subDict[#"images"];
for (int j=0; j<subArray.count; j++) {
tempDict = subArray[j];
NSLog(#"%#",tempDict[#"image"]);
}
}
in JSONObjectSerialization data was NSData object where the json file downloaded.
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];
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.
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];