I have an array(seachResult) which contains dictionaries and I want to sort this array according to 'price' key in the dictionary that is a number in string format.
I tried this code but it doesn't work for sorting 'price' but it works for pid which is a number.
how can I sort it according 'price' (number in string format)?
NSSortDescriptor *sortByPrice = [NSSortDescriptor sortDescriptorWithKey:#"price" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByPrice];
NSArray *sortedArray = [self.seachResult sortedArrayUsingDescriptors:sortDescriptors];
NSLog(#"%#",sortedArray );
here is sample data for self.searchResult:
2013-07-17 02:04:55.012 MyApp[57014:16a03] sorted array of dictionaries: (
{
cid = 2;
image = "http:///images/loginlogo.png";
latitude = "48.245565";
longitude = "16.342333";
manual = "";
movie = "http://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v";
pcode = 023942435228;
pid = 1;
pname = "example product";
price = "12.00";
qrcode = "";
rid = 1;
rname = "Example Retailer Name";
sale = 0;
"sale_percent" = 0;
"sale_price" = "0.00";
text = "here is text about sample product number 1...\nasdasdasda\nsdfsdfsd\nSdfsdf\nSDfsdfs\ndfsdfsdf\n\n\n";
},
{
cid = 2;
image = "http:///testImage.png";
latitude = "48.245565";
longitude = "16.342333";
manual = "";
movie = "";
pcode = 1;
pid = 2;
pname = "sample product 2";
price = "126.00";
qrcode = "";
rid = 1;
rname = "Example Retailer Name";
sale = 1;
"sale_percent" = 20;
"sale_price" = "99.99";
text = "here is text about sample product number 2...\nblah blah blah\nasdasdasd\nASdasdas\nASdasdasd";
},
{
cid = 1;
image = "";
latitude = "";
longitude = "";
manual = "";
movie = "";
pcode = 1;
pid = 3;
pname = "test product";
price = "46.00";
qrcode = "";
rid = 2;
rname = "";
sale = 0;
"sale_percent" = 0;
"sale_price" = "35.00";
text = "some text here...
\nasdasd
\nasd
\na
\nsd
\nas
\nd";
}
)
I also tried this code :
NSSortDescriptor *hopProfileDescriptor =
[[NSSortDescriptor alloc] initWithKey:#"price"
ascending:YES];
NSArray *descriptors = [NSArray arrayWithObjects:hopProfileDescriptor, nil];
NSArray *sortedArrayOfDictionaries = [self.seachResult
sortedArrayUsingDescriptors:descriptors];
NSLog(#"sorted array of dictionaries: %#", sortedArrayOfDictionaries);
but still doesn't work.
I think the issue is that in your self.searchResult array the price data is differently formatted for the objects in the array.
The first object in the array it's formatted like price = 12; (probably a NSDecimalNumber)
The second object in the array it's formatted like price = "125.99"; (proably a NSString)
NSArray *testSorted = [test sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) {
NSString *price1 = obj1[#"price"];
NSString *price2 = obj2[#"price"];
NSNumber *n1 = [NSNumber numberWithFloat:[price1 floatValue]];
NSNumber *n2 = [NSNumber numberWithFloat:[price2 floatValue]];
return [n1 compare:n2];
}];
Since your price data seems to vary (NSString vs NSNumber) you might try instead using sortedArrayUsingComparator:. eg:
NSArray *sortedArray = [unsortedArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
id value1 = [obj1 objectForKey:#"price"];
float float1 = [value1 floatValue];
id value2 = [obj2 objectForKey:#"price"];
float float2 = [value2 floatValue];
if (float1 < float2) {
return NSOrderedAscending;
}
else if (float1 > float2) {
return NSOrderedDescending;
}
return NSOrderedSame;
}];
This is kinda ugly but should get you started. It's also fragile--if you get something other than NSNumber or NSString for the price it'll likely crash.
Related
I am trying to parse JSON, using Objective-C This is the NSLog Echoed with my current code.
{
KnowledgeBaseEntry = {
AllowBotAccess = 1;
FulltextSearch = 1;
GroupId = "";
Id = 611552aea1fe4d789e31133d3ee77f35;
IsPublic = 1;
Languages = "";
OwnerId = 8c427d5;
ParentId = 1;
ShortcutWord = "";
Tags = "";
Title = "Another Test Cell";
Type = 1;
Value = "This <BR>Is<BR>testing";
};
},
{
KnowledgeBaseEntry = {
AllowBotAccess = 1;
FulltextSearch = 1;
GroupId = "";
Id = fc4f1a90243246bb93641b0c8db689b9;
IsPublic = 1;
Languages = "";
OwnerId = 8c427d5;
ParentId = 1;
ShortcutWord = "";
Tags = "";
Title = "Cydo Error 2";
Type = 1;
Value = "content<BR><BR>this is contenty";
};
},
{
KnowledgeBaseEntry = {
AllowBotAccess = 1;
FulltextSearch = 1;
GroupId = "";
Id = bd057d5443194d7a98c2398e07de919e;
IsPublic = 1;
Languages = "";
OwnerId = 8c427d5;
ParentId = 1;
ShortcutWord = "";
Tags = "";
Title = testkb2;
Type = 1;
Value = "test content!";
};
}
)
I need to use the Title to grab what is in the Value so I can display in app. I can access the Title Var but I have no idea how to match the two to NSLog the Value. Any help is appreciated.
Here is the current code:
NSData *rGeniusData = [[NSData alloc] initWithContentsOfURL:
[NSURL URLWithString:#"http://jbbar.ml/rgenius/ipapi.php"]];
//Parse The JSON
NSError *error;
NSMutableDictionary *allKB = [NSJSONSerialization JSONObjectWithData:rGeniusData
options:NSJSONReadingMutableContainers
error:&error];
NSArray *kb = allKB[#"KnowledgeBaseEntries"];NSLog(#"AboveDP= %#", kb);
Parse like this
NSDictionary *dict;
NSString *strAllowBotAccess =[[dict objectForKey:#"KnowledgeBaseEntry"]objectForKey:#"AllowBotAccess"];
NSLog(#"dict=====%#", strAllowBotAccess);
Try https://github.com/jsonmodel/jsonmodel
JSONModel allows rapid creation of smart data models. You can use it in your iOS, macOS, watchOS and tvOS apps. Automatic introspection of your model classes and JSON input drastically reduces the amount of code you have to write.
Easy to use, you can parse all keys or some of them.
#interface YourModel : JSONModel
#property (nonatomic) NSInteger id;
#property (nonatomic) NSString *value;
#end
#implementation YourModel
+ (JSONKeyMapper *)keyMapper
{
return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:#{
#"id": #"Id",
#"value": #"KnowledgeBaseEntry.Value"
}];
}
#end
How do you compare two strings with different format strings? For example, in the code below:
str1 = [dataDic1 objectForKey:[finalArray objectAtIndex:indexPath.row]];
str1 contains 124.00,120/70-14,1,759,140/70-14,48.8 x 57.0.
str2 = [dataDic2 objectForKey:[finalArray objectAtIndex:indexPath.row]];
str2 contains 1.00,90/90-6,1,250,90/90-6,45.3 x 87.0.
I want to compare str1 and str2
if ([bike1Str intValue] < [bike2Str intValue]){
NSLog(#"%#", str2);
}
else{
}
For example: if (120/70-14 < 90/90-6)
How do I do this type comparison ?
DataDic1 {
"Displacement_trim" = "124.00 ";
"Dry_Weight" = "<null>";
"Front_Brakes_Size_trim" = "260 ";
"Front_Tire_Size" = "120/70-14";
"Fuel_Capacity_trim" = "13.50 ";
"Overall_Height_trim" = "1,759 ";
"Overall_Length_trim" = "2,230 ";
Power = "";
"Power_Weight_Ratio" = "<null>";
"Rear_Brake_Size_trim" = "240 ";
"Rear_Tire_Size" = "140/70-14";
Stroke = "";
"Torque_trim" = "";
"stroke_trim" = "48.8 x 57.0 ";
}
and finalArray
(
Power_Weight_Ratio,
Rear_Brake_Size_trim,
Dry_Weight,
Torque_trim,
stroke_trim,
Rear_Tire_Size,
Front_Brakes_Size_trim,
Fuel_Capacity_trim,
Overall_Length_trim,
Front_Tire_Size,
Stroke,
Power,
Displacement_trim,
Overall_Height_trim
)
Not only float values i am asking all the all values to compare
NSMutableDictionary *dict1,*dict2;
NSMutableArray *ArrayContaingFloat;
dict1 = [[NSMutableDictionary alloc]init];
dict2 = [[NSMutableDictionary alloc]init];
ArrayContaingFloat = [[NSMutableArray alloc]init];
[dict1 setObject:[NSNumber numberWithFloat:14.20] forKey:#"Displacement_trim"];
[dict2 setObject:[NSNumber numberWithFloat:20.20] forKey:#"Displacement_trim"];
if ( [[dict1 valueForKey:#"Displacement_trim"] compare:[dict2 valueForKey:#"Displacement_trim"]]==NSOrderedAscending) {
NSLog(#"dict 2 is greater");
}else{
NSLog(#"dict 1 is greater");
}
if( [[dict1 valueForKey:#"Displacement_trim"] compare:[dict2 valueForKey:#"Displacement_trim"]]==NSOrderedAscending){
}
[ArrayContaingFloat addObject:[dict1 valueForKey:#"Displacement_trim"]];
[ArrayContaingFloat addObject:[dict2 valueForKey:#"Displacement_trim"]];
NSLog(#"Array conting float %#",ArrayContaingFloat);
NSSortDescriptor *highestToLowest = [NSSortDescriptor sortDescriptorWithKey:#"self" ascending:NO];
[ArrayContaingFloat sortUsingDescriptors:[NSArray arrayWithObject:highestToLowest]];
NSLog(#"After Sorting %#",ArrayContaingFloat);
you will get output like this:
dict 2 is greater
Array conting float (
"14.2",
"20.2"
)
After Sorting (
"20.2",
"14.2"
)
let me know if you have any further query.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I need to list all dictionary values. Like highest mark to lowest. How can I handle this?
I need to list all marks and corresponding names and details in a table view.
2015-04-06 14:48:53.381 camelProject[3310:597950] valueforkey title = (
{
CamelID = 237;
Color = bg;
Comments = "Fhjfnfnfjfihgjfmsndidm,almcmcuirowmvn vmmc Jdmdmcm";
CompID = 235;
DateOfBirth = "/Date(1424725200000)/";
Description = "rtrtttrtrehndskvn;lkdf;lm;mgemln;lm';' jknt;l";
FromUserID = 564987631;
FromUsername = 564987631;
ID = 4;
IndvMarks = "5;5;3;4;2;2;2;2;5;9";
Marks = 39;
Name = name3sv;
OutOF = 100;
ProfilePhoto = "2D0B36F3-71B3-4B5F-A375-7AD4D0AFF1AF.jpg\n";
TOname = hasnam;
ToUserName = 564987631;
Types = dsfv;
UserID = 564987631;
fromname = hasnam;
},
{
CamelID = 237;
Color = bg;
Comments = "";
CompID = 235;
DateOfBirth = "/Date(1424725200000)/";
Description = "rtrtttrtrehndskvn;lkdf;lm;mgemln;lm';' jknt;l";
FromUserID = 564987631;
FromUsername = 564987631;
ID = 5;
IndvMarks = "5;4;5;7;6;0;6;5;4;6";
Marks = 48;
Name = name3sv;
OutOF = 100;
ProfilePhoto = "2D0B36F3-71B3-4B5F-A375-7AD4D0AFF1AF.jpg\n";
TOname = hasnam;
ToUserName = 564987631;
Types = dsfv;
UserID = 564987631;
fromname = hasnam;
},
{
CamelID = 237;
Color = bg;
Comments = Gucjhkhvnkvnvnvknkjbkvjhvvkb;
CompID = 235;
DateOfBirth = "/Date(1424725200000)/";
Description = "rtrtttrtrehndskvn;lkdf;lm;mgemln;lm';' jknt;l";
FromUserID = 564987631;
FromUsername = 564987631;
ID = 6;
IndvMarks = "3;4;4;3;5;4;4;3;3;5";
Marks = 38;
Name = name3sv;
OutOF = 100;
ProfilePhoto = "2D0B36F3-71B3-4B5F-A375-7AD4D0AFF1AF.jpg\n";
TOname = hasnam;
ToUserName = 564987631;
Types = dsfv;
UserID = 564987631;
fromname = hasnam;
},
{
CamelID = 236;
Color = wejr;
Comments = "Jfj ki idhvjfn isms isn't if jfj Jen hik";
CompID = 235;
DateOfBirth = "/Date(1427058000000)/";
Description = jwenrfernkgr;
FromUserID = 564987631;
FromUsername = 564987631;
ID = 21;
IndvMarks = "8;6;10;10;10;7;5;8;9;5";
Marks = 78;
Name = name;
OutOF = 100;
ProfilePhoto = "E7735AF4-8EAB-41E7-A3F2-3280DBED0389.jpg\n";
TOname = lukman;
ToUserName = 564987634;
Types = wenjewfn;
UserID = 564987634;
fromname = hasnam;
}
)
Get the values into a array and sort them using a sort descriptor.
NSArray *array = [dictioanry objectForKey:#"title"];
NSSortDescriptor* marksDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"Marks"
ascending:YES];
NSArray* sortedObjects = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:marksDescriptor, nil]];
//YOu can put this object back into NSDictionary if you want it for later
I think your dictionary should be looking like this.
So the code above should work to sort the values. Here is the sample code that I did the testing with.
Note: Save your JSON string in your test.json and add it to your project. or download the file from here and add it to your project
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"json"];
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSDictionary *jsonDictionary=[NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableLeaves
error:nil];
NSLog(#"%#",jsonDictionary);
NSArray *array = [jsonDictionary objectForKey:#"title"];
NSSortDescriptor* marksDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"Marks"
ascending:YES];
NSArray* sortedObjects = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:marksDescriptor, nil]];
NSLog(#"%#",sortedObjects);
Example :
NSArray *originalArray = #[
#{#"page_no": #"27"},
#{#"page_no": #"1"},
#{#"page_no": #"12"},
#{#"page_no": #"23"},
#{#"page_no": #"3"},
#{#"page_no": #"2"},
#{#"page_no": #"17"},
];
NSSortDescriptor *alphaNumSD = [NSSortDescriptor sortDescriptorWithKey:#"page_no"
ascending:YES
comparator:^(NSString *string1, NSString *string2)
{
return [string1 compare:string2 options:NSNumericSearch];
}];
NSArray *sortedArray = [originalArray sortedArrayUsingDescriptors:#[alphaNumSD]];
NSLog(#"%#", sortedArray);
Output :
(
{
"page_no" = 1;
},
{
"page_no" = 2;
},
{
"page_no" = 3;
},
{
"page_no" = 12;
},
{
"page_no" = 17;
},
{
"page_no" = 23;
},
{
"page_no" = 27;
}
)
It definitely works as expected.
I have an array self.seachResult which contains dictionary, I want to add an item to all dictionaries I tried a code like this but I got error, can you provide me by a code that add item 'distance' to it
[[self.seachResult objectAtIndex:0] setObject:#"distance" forKey:#"400"];
this is my array of dictionary:
2013-07-19 02:13:24.929 MyApp[59321:16a03] sorted array of dictionaries: (
{
cid = 2;
image = "http:///images/loginlogo.png";
latitude = "48.245565";
longitude = "16.342333";
manual = "";
movie = "http://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v";
pcode = 023942435228;
pid = 1;
pname = "example product";
price = "12.00";
qrcode = "";
rid = 1;
rname = "Example Retailer Name";
sale = 0;
"sale_percent" = 0;
"sale_price" = "0.00";
text = "here is text about sample product number 1...\nasdasdasda\nsdfsdfsd\nSdfsdf\nSDfsdfs\ndfsdfsdf\n\n\n";
},
{
cid = 1;
image = "";
latitude = "";
longitude = "";
manual = "";
movie = "";
pcode = 1;
pid = 3;
pname = "test product";
price = "46.00";
qrcode = "";
rid = 2;
rname = "";
sale = 0;
"sale_percent" = 0;
"sale_price" = "35.00";
text = "some text here...
},
{
cid = 2;
image = "http:///testImage.png";
latitude = "48.245565";
longitude = "16.342333";
manual = "";
movie = "";
pcode = 1;
pid = 2;
pname = "sample product 2";
price = "126.00";
qrcode = "";
rid = 1;
rname = "Example Retailer Name";
sale = 1;
"sale_percent" = 20;
"sale_price" = "99.99";
text = "here is text about sample product number 2...\nblah blah blah\nasdasdasd \nASdasdas\nASdasdasd";
}
)
here is the error:
2013-07-19 02:49:54.261 MyApp[59376:16a03] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'
*** First throw call stack:
(0x3367012 0x2d27e7e 0x3366deb 0x332d347 0x13472 0x1d4d1c7 0x1d4d232 0x1d4d4da 0x1d648e5 0x1d649cb 0x1d64c76 0x1d64d71 0x1d6589b 0x1d65e93 0x1d65a88 0x20c1e63 0x20b3b99 0x1d4ddd2 0x12b9f 0x2d3b705 0x1c6f2c0 0x1c6f258 0x1d30021 0x1d3057f 0x1d2f6e8 0x1c9ecef 0x1c9ef02 0x1c7cd4a 0x1c6e698 0x37a7df9 0x37a7ad0 0x32dcbf5 0x32dc962 0x330dbb6 0x330cf44 0x330ce1b 0x37a67e3 0x37a6668 0x1c6bffc 0x288d 0x27b5)
libc++abi.dylib: terminate called throwing an exception
here is where I create it:
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
self.seachResult =[NSJSONSerialization JSONObjectWithData:responseData options:nil error:nil];
// [self.productsTableView reloadData];
NSMutableArray *testSorted = [self.seachResult sortedArrayUsingComparator:^NSComparisonResult(NSMutableDictionary *obj1, NSMutableDictionary *obj2) {
NSString *price1 = obj1[#"price"];
NSString *price2 = obj2[#"price"];
NSNumber *n1 = [NSNumber numberWithFloat:[price1 floatValue]];
NSNumber *n2 = [NSNumber numberWithFloat:[price2 floatValue]];
return [n1 compare:n2];
}];
[[self.seachResult objectAtIndex:0] setObject:#"distance" forKey:#"400"];
NSLog(#"sorted array of dictionaries: %#", testSorted);
Your objects created from JSON are all immutable.
self.seachResult =[NSJSONSerialization JSONObjectWithData:responseData options:nil error:nil];
instead of passing nil for options pass NSJSONReadingMutableContainers:
self.seachResult =[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
From the NSJSONSerialization docs:
NSJSONReadingMutableContainers
Specifies that arrays and dictionaries are created as mutable objects.
I have an array width this values:
array: (
{
id = 1;
name = "Cursus Nibh Venenatis";
value = "875.24";
},
{
id = 2;
name = "Elit Fusce";
value = "254.02";
},
{
id = 3;
name = "Bibendum Ornare";
value = "123.42";
},
{
id = 4;
name = "Lorme Ipsim";
value = "586.24";
}
)
What I need to do is get each 'value' and sum it all. Im declaring a new array to take each value:
self.valuesArray = [[NSArray alloc] init];
But how can I do it? Thanks for your answer!
double sum = [[array valueForKeyPath:#"#sum.value"] doubleValue];
You can read more on collection operators here
You have already declared array so i will use your. I also assume your first array(which contains data set above) is an array called myFirstArray(of type NSArray)
int sum =0;
self.valuesArray = [[NSMutableArray alloc] init];
for(NSDictionary *obj in myFirstArray){
NSString *value =[obj objectForKey:#"value"];
sum+= [value intValue];
[self.valuesArray arrayWithObject:value];//this line creates a new NSArray instance which conains array of 'values'(from your dictionary)
}
NSLog("The sum of values is: %d", sum);
NSLog("The array of \'values\' is : %#",self.valuesArray );
double sum=0.0;
for (YourDataObject *d in array) {
sum+=[[d getValue] doubleValue];
}
try this -
float totalValue = 0.0f;
for (int i = 0 ; i< [array count]; i++) {
totalValue +=[[[array objectAtIndex:i] objectForKey:#"value"] floatValue];
}