Dictionary from an Array of Dictionary - Logical Challenge in Objective-C - objective-c

The goal is converting Array of Dictionaries into one Dictionary of different objects. How can I do that?
I have an Array of records in this format,
originalArray = [{
"valid": "Y",
"mof": "ON",
"dof": "17-05-2019",
"rtntype": "CODE1",
"ret_prd": "042019",
},
{
"valid": "Y",
"mof": "ON",
"dof": "19-04-2019",
"rtntype": "CODE1",
"ret_prd": "032019",
},
{
"valid": "Y",
"mof": "ON",
"dof": "19-04-2019",
"rtntype": "CODE2",
"ret_prd": "032019",
}
]
I want to create a Dictionary in the following format.
{
"032019" = {
"CODE1" = {
"valid": "Y",
"mof": "ON",
"dof": "19-04-2019",
"rtntype": "CODE1",
"ret_prd": "032019",
},
"CODE2" = {
"valid": "Y",
"mof": "ON",
"dof": "19-04-2019",
"rtntype": "CODE2",
"ret_prd": "032019",
"status": "Filed"
}
},
"042019" = {
"CODE1" = {
"valid": "Y",
"mof": "ON",
"dof": "17-05-2019",
"rtntype": "CODE1",
"ret_prd": "042019",
}
}
}

Here is my sample, you can check by yourself
NSArray *array = #[
#{#"valid":#"Y",#"mof":#"ON",#"dof":#"17-05-2019",#"rtntype":#"CODE1",#"ret_prd":#"042019"},
#{#"valid":#"Y",#"mof":#"ON",#"dof":#"19-04-2019",#"rtntype":#"CODE1",#"ret_prd":#"032019"},
#{#"valid":#"Y",#"mof":#"ON",#"dof":#"19-04-2019",#"rtntype":#"CODE2",#"ret_prd":#"032019"}
];
NSMutableDictionary *result = [NSMutableDictionary new];
for (int i = 0; i < array.count; i++) {
NSDictionary *dict = array[i];
NSString *value = dict[#"ret_prd"];
if (result[value] == nil) {
NSArray *filterArray = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(ret_prd contains[c] %#)", value]];
NSMutableDictionary *filterDict = [NSMutableDictionary new];
for (int i = 0; i < filterArray.count; i++) {
filterDict[filterArray[i][#"rtntype"]] = filterArray[i];
}
result[value] = filterDict;
}
}
NSLog(#"%#", result);
Result in console log:
Long time no code Objective-C, so above code maybe weird. Let me know if you don't know any where, I'll explain for you.

Related

Find out a particular value from array of Dictionary

I have an array which contains dictionary. In each dictionary again contains array of dictionary. I want figure out all the objects which has that particular value, like India.
I tried with NSpredicate. Example Array of dictionary
{
Destination : [
{
plan : [
{
name : "India"
},
{
name : "India"
}
]
},
{
plan : [
{
name : "Germany"
},
{
name : "Germany"
}
]
}
]
}
For this dictionary my code is
NSMutableArray * destinationArray = [[NSMutableArray alloc]init];
[destinationArray addObject:[ResponseObject objectForKey:#"Destination"]];
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#",#"India"];
NSArray * filtered = [destinationArray filteredArrayUsingPredicate:predicate];
NSMutableArray* container = [NSMutableArray new];
for (NSMutableDictionary* d in firstArray) {
for (NSMutableDictionary* d2 in d[#"plan"]) {
[container addObject: [d2[#"name"] mutableCopy];
}
}
i believe this will do it
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#",[[[ResponseObject objectAtIndex:i]objectForKey:#"destination"]objectForKey:#"name"]];
in your code, when call [[ResponseObject objectAtIndex:i]objectForKey:#"destination"] here return a NSArray contains some NSDictionary. when you call objectForKey:#"name", it will send you a error, are you sure you code is current?
here is my test follow your data struct, the result is current.
NSArray *array = #[#{#"name" : #"zhangsan",
#"age" : #"10",
#"result": #[
#{#"res":#"123l"},
#{#"res":#"789l"}
]
},
#{#"name" : #"lisi",
#"age" : #"11",
#"result": #[
#{#"res":#"123l"},
#{#"res":#"789l"}
]
},
#{#"name" : #"wangwu",
#"age" : #"12",
#"result": #[
#{#"res":#"123l"},
#{#"res":#"789l"}
]
}];
NSString *preStr = #"res";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K CONTAINS[c] %#",preStr, #"123"];
NSMutableArray *result = [NSMutableArray array];
for (NSDictionary *dict in array) {
NSArray *res = dict[#"result"];
[result addObjectsFromArray:[res filteredArrayUsingPredicate:predicate]];
}
NSLog(#"final result == %#",result);

Sorting array having special characters, numbers, English and Arabic string in objectiveC

I am developing an iPhone application in objectiveC in which I have one array having alphanumeric, multilingual, special character data as shown below:
(
{
name = “#”;
},
{
name = “iPad”;
},
{
name = “عينة”;
},
{
name = “1”;
},
{
name = “أ”;
},
{
name = “10”;
},
)
Sorting should provide me result as below,
(
{
name = “iPad”;
},
{
name = “أ”;
},
{
name = “عينة”;
}
{
name = “#”;
},
{
name = “1”;
},
{
name = “10”;
},
)
Means first English and Arabic should be in alphabetical ascending order then special characters and then numbers in ascending order.
I got the solution using regular expression as below,
NSMutableArray *aMutArrArabic = [[NSMutableArray alloc] init];
for(NSDictionary *aDictObj in mutArrAddCard)
{
NSError *error = NULL;
NSRegularExpression *aRegexObj = [NSRegularExpression regularExpressionWithPattern:#"^[ء-ي]+$"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSArray *aArrMatches = [aRegexObj matchesInString:aDictObj[#"name"]
options:0
range:NSMakeRange(0, [aDictObj[#"name"] length])];
if([aArrMatches count] > 0)
{
[aMutArrArabic addObject:aDictObj];
}
}
This way I managed to get all arrays using their relevant regular expression.
There could be some improvement, by this is what you can do with sortedArrayUsingComparator: and a custom comparator block.
Main idea:
- Get first char of the string.
- Determine what its "kind" (Letter, Arabic, Number, Other)
- Sort accordingly.
I started with these "kind":
typedef enum : NSUInteger {
CharacterOfKindArabic,
CharacterOfKindNumerical,
CharacterOfKindLetter,
CharacterOfKindOther
} CharacterOfKind;
And use this method to get the CharacterOfKind:
-(CharacterOfKind)retrieveFirstCharacterKindFromString:(NSString *)string
{
if ([string length])
{
unichar unicharacter = [string characterAtIndex:0];
if (unicharacter >= 0x600 && unicharacter <= 0x6ff)
return CharacterOfKindArabic;
if (unicharacter >= 0x750 && unicharacter <= 0x77f)
return CharacterOfKindArabic;
if (unicharacter >= 0xfb50 && unicharacter <= 0xfc3f)
return CharacterOfKindArabic;
if (unicharacter >= 0xfe70 && unicharacter <= 0xfefc)
return CharacterOfKindArabic;
NSString *firstChar = [string substringToIndex:1];
if ([firstChar rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet] options:0].location != NSNotFound)
return CharacterOfKindNumerical;
if ([firstChar rangeOfCharacterFromSet:[NSCharacterSet letterCharacterSet] options:0].location != NSNotFound)
return CharacterOfKindLetter;
return CharacterOfKindOther;
}
return CharacterOfKindOther;
}
I don't speak Arabic, and I never had to code with Arabic text. So I took these info of "character range" from the net. I read something on Objective-C here on StackOverflow, but I couldn't retrieve it. Maybe my memory is playing with me, but the range may have changed (more ranges added). I find the method a little ugly, but that's to get the main point.
NSString *kName = #"name";
NSArray *arrayToSort = #[#{kName:#"#"},
#{kName:#"iPhone"},
#{kName:#"iPad"},
#{kName:#"عينة"},
#{kName:#"1"},
#{kName:#"أ"},
#{kName:#"10"}];
NSLog(#"arrayToSort: %#", arrayToSort);
NSArray *typeSort = #[#(CharacterOfKindLetter), #(CharacterOfKindArabic), #(CharacterOfKindOther), #(CharacterOfKindNumerical)];
NSArray *sortedArray = [arrayToSort sortedArrayUsingComparator:^NSComparisonResult(NSDictionary * _Nonnull obj1, NSDictionary * _Nonnull obj2)
{
NSString *firstString = obj1[kName];
NSString *secondString = obj2[kName];
CharacterOfKind firstCharType = [self retrieveFirstCharacterKindFromString:firstString];
CharacterOfKind secondCharType = [self retrieveFirstCharacterKindFromString:secondString];
if (firstCharType == secondCharType) //Same Kind of first characters, do a normal "compare"
{
return [firstString compare:secondString];
}
else //Do a custom compare according typeSort
{
//Returns correctly according to the order set in typeSort
return [#([typeSort indexOfObject:#(firstCharType)]) compare:#([typeSort indexOfObject:#(secondCharType)])];
}
}];
NSLog(#"SortedArray: %#", sortedArray);
Output:
>>>arrayToSort: (
{
name = "#";
},
{
name = iPhone;
},
{
name = iPad;
},
{
name = "\U0639\U064a\U0646\U0629";
},
{
name = 1;
},
{
name = "\U0623";
},
{
name = 10;
}
)
>>>SortedArray: (
{
name = iPad;
},
{
name = iPhone;
},
{
name = "\U0623";
},
{
name = "\U0639\U064a\U0646\U0629";
},
{
name = "#";
},
{
name = 1;
},
{
name = 10;
}
)

Edit valueForKey in NsMutableArray

I have a NsMutableArray. It has format as the below:
arrayTest:(
{
away = "Test 1";
"time_start" = "20:30";
},
{
away = "Test 2";
"time_start" = "21:00";
},
{
away = #"Test 3";
"time_start" = "21:30";
}
)
Can I edit or delete the value for 'away' in this array?
Assuming here arrayTest is a NSMutableArray.
You can approach the first dictionary by [arrayTest objectAtIndex:0].
Furthermore, to get the value for keyTest 1, use [[arrayTest objectAtIndex:0] objectForKey:#"Test 1"];

Objective-C String handling issue

I'm trying to read from a JSON response something like below
{
"URL":
{
"target": "www.google.com",
"0": [ 92, 15 ],
"1": [ 92, 16 ],
"2": [ 74, 15 ],
"4": [ 5, 16 ]
}
}
Using SBJSON I've managed to get 'target' field,
testString = [[result objectForKey:#"URL"] objectForKey:#"target"];
when I do a NSLOG it shows www.google.com
but this piece of code doesn't work for other key pairs.
testString = [[result objectForKey:#"URL"] objectForKey:#"0"];
and when I try to print testString it gives me an error.
In console I printed values, they were,
(lldb) po testString
(NSString *) $4 = 0x0864b190 <__NSArrayM 0x864b190>(
65,
27
)
How do I extract these 65 and 27 ?
that is an array of objects. try:
NSArray * array = [[result objectForKey:#"URL"] objectForKey:#"0"];
id a = [array objectAtIndex:0]; // 65
id b = [array objectAtIndex:1]; // 27
// now determine the type of objects in the array, and use them appropriately:
if ([a isKindOfClass:[NSString class]]) {
NSString * string = a;
...use appropriately
}
else if ([a isKindOfClass:[NSDecimalNumber class]]) {
NSDecimalNumber * number = a;
...use appropriately
}
...
else {
assert(0 && "type not supported");
}
Do this:
if([result objectForKey:#"URL"] objectForKey:#"0"] isKindofClass:[NSArray class])
{
NSArray *arritems = [[result objectForKey:#"URL"] objectForKey:#"0"];
NSMutableArray *values = [NSMutableArray array];
for( id *item in arritems)
{
if([item is isKindOfClass:[NSString class]])
{
NSString * valueStr = item;
[values addObject:valueStr];
}
else if([item is isKindOfClass:[NSDecimalNumber class]])
{
NSDecimalNumber * valueNum = item;
[values addObject:valueNum];
}
}
NSLog(#"%#",values);
}
Same logic repeat for keys value 1 , 2 , 3
NSArray *data = [[result objectForKey:#"URL"] objectForKey:#"0"];
Then your items are in [data objectAtIndex:0] and [data objectAtIndex:1]

how to Json request convert to native object or list?

{
"id": "1",
"result": [
{
"Name": "John",
"Statu": "Online"
},
{
"Name": "Alex",
"Statu": "Online"
},
{
"Name": "Diaz",
"Statu": "Offline"
}
]
}
How do i extract each "car" JSON object and put it into a native object? I tried several way but i can't do that.
NSString *responseString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
NSString *responseDict = [responseString JSONValue];
NSArray *objects = [NSArray arrayWithObjects:[responseDict valueForKeyPath:#"result.Name"],[responseDict valueForKeyPath:#"result.Statu"],nil];
NSLog(#"objects Array: %#",objects);
**==> NSLOG gives:
(
(
"John",
"Alex",
"Diaz"
),
(
"Online",
"Online",
"Offline"
)
)
NSArray *resultsArray = [responseString JSONValue];
for (NSDictionary *personDict in resultsArray)
{
NSLog(#"ihaleAdi =: %#",[carDict valueForKey:#"result.ihaleAdi"]);
NSLog(#"ihaleDurum =: %#",[carDict valueForKey:#"result.Statu"]);
}
But ıt gıves an error tooç I want to just lıst them but ı cant do thatç can anybody help me please? thank you for reading
Use an Array to capture the responseString:
NSString *responseString = [request responseString];
NSArray *array = [responseString JSONValue];
Then when you need an individual item from that array use a Dictionary:
// 0 is the index of the array you need
NSDictionary *itemDictionary = (NSDictionary *)[array objectAtIndex:0];
Given a JSON responseString that looks like this:
[{"UniqueID":111111,"DeviceName":"DeviceName1","Location":"Device1Loc","Description":"Device1Desc"},{"UniqueID":22222,"DeviceName":"DeviceName2","Location":"Device2Loc","Description":"Device2Desc"}]
You will wind up with an Array that looks like this:
myArray = (
{
Description = "Device1Desc";
DeviceName = "DeviceName1";
Location = "Device1Loc";
UniqueID = 111111;
},
{
Description = "Device2Desc";
DeviceName = "DeviceName2";
Location = "Device2Loc";
UniqueID = 222222;
}
)
And a Dictionary of index 0 that looks like this:
myDictionary = {
Description = "Device1Desc";
DeviceName = "DeviceName1";
Location = "Device1Loc";
UniqueID = 111111;
}
Sorry for any confusion and improperly instantiated object earlier. I am still a relative newbie that learned something today.