I have an array of dictionaries with N keys. I want to create an array of unique dicts which contains only some keys.
Example. My dict:
{
"m_anno" = 2017;
"m_c_ultimo" = "4.130";
"m_cod" = 4522;
"m_cod_art" = "*B";
"m_des" = "SCRITTA BIANCA NISSAN";
"m_ditta" = SIS;
"m_prz" = "0.000";
"m_qta" = "1.000";
"m_sconto" = {
};
},
{
"m_anno" = 2017;
"m_c_ultimo" = "25.020";
"m_cod" = 4522;
"m_cod_art" = "000/01200";
"m_des" = "CABLAGGIO X TIMONE";
"m_ditta" = SIS;
"m_prz" = "0.000";
"m_qta" = "1.000";
"m_sconto" = {
};
},
{
"m_anno" = 2017;
"m_c_ultimo" = "1.000";
"m_cod" = 4523;
"m_cod_art" = 000000;
"m_des" = "BLISTER O-RING 3106";
"m_ditta" = SIS;
"m_prz" = "0.000";
"m_qta" = "1.000";
"m_sconto" = {
};
},
I want to get unique values of m_anno and m_cod keys. Expected result:
{
{
"m_anno" = 2017
"m_cod" = 4522
}
{
"m_anno" = 2017
"m_cod" = 4523
}
}
Which is the simplest way?
Basically you have to iterate over the array (quelle surprise!) and put it in a collection, if the pair doesn't exist yet. The second task can be accomplished by using an instance of NSSet or NSOrderedSet depending on the requirement that the order has to be preserved:
NSArray *values = …; // You start with this
NSMutableOrderedSet *uniquePairs = [NSMutableOrderedSet new];
for( NSDictionary *value in values )
{
NSDictionary *pair = #{ #"m_anno":[value objectForKey:#"m_anno"], #"m_cod":[value objectForKey:#"m_cod"] }; // Create smaller version
[uniquePairs addObject:pair];
}
There might be a more elegant way. (Depends of the point of view)
Create an addition to dictionaries, that reduces the array to the desired keys:
NSDictionary( UnifyAnnoAndCodeAddition )
- (NSDictionary*)annoAndCod
{
return #{ #"m_anno":[self objectForkey:#"m_anno"], #"m_cod":[self objectForKey:#"m_code"]};
}
Then use key-value coding to create an array of the reduced dictionaries and make a set of this:
NSArray *values = …; // You start with this
NSArray *pairs = [values valueForKey:#"annoAndCod"];
NSOrderedSet = [NSOrderedSet orderedSetWithArray:pairs];
Well, at least it is shorter.
I'm using the Edmunds API to return a JSON string of vehicle makes for a certain year.
The resulting NSDictionary looks like this:
makes = (
{
id = 200002038;
models = (
{ // not relevant
}
);
name = Acura;
niceName = acura;
},
{
id = 200001769;
models = (
{ // not relevant
}
);
name = "Aston Martin";
niceName = "aston-martin";
},
There are a lot more values in this dictionary...how can I loop through through the dictionary to retrieve each of the 'name' values?
I like valueForKeyPath because you can do so much with it and it's a one line solution. Tested this and it works in my dev setup. If you know your data is in a predictable format, then you can do amazing things with valueForKeyPath.
NSArray *makeNames = [makes valueForKeyPath:#"name"];
Great info on valueForKeyPath http://nshipster.com/kvc-collection-operators/
NSMutableArray *makeNames = [NSMutableArray new];
for (NSDictionary *make in makes) {
NSLog(#"Make name: %#", make[#"name"]);
[makeNames addObject:make];
}
NSLog(#"Makes array: %#", makeNames);
I am trying to correctly target the elements within the Json Output and I am getting closer but I presume there is a easy and obvious way I am missing.
My Json looks like this with a upper level event.
JSON SNIPPET UPDATED
chat = (
(
{
Key = senderId;
Value = {
Type = 0;
Value = "eu-west-1:91afbc3f-890a-4160-8903-688bf0e9efe8";
};
},
{
Key = chatId;
Value = {
Type = 0;
Value = "eu-west-1:be6457ce-bac1-412d-9307-e375e52e22ff";
};
},
{
Key = timestamp;
Value = {
Type = 1;
Value = 1430431197;
};
},
//Continued
I am targeting this level using
NSArray *chat = array[#"chat"];
for ( NSDictionary *theCourse in chat )
{
NSLog(#"---- %#", theCourse);
// I tried the following to target the values
//NSLog(#"chatId: %#", [theCourse valueForKey:#"Key"]);
//NSLog(#"timestamp: %#", theCourse[#"senderId"] );
}
}
I need to parse the value data for each key which if I was using an array would do like [theCourse valueForKey:#"Key"] but I think I may not be going deep enough?
As you would expect, [theCourse valueForKey:#"Key"] gives me the Key values but I need the associate values of those keys.
You can create an easier dictionary:
NSArray *chat = array[#"chat"][0];
NSMutableDictionary* newDict = [NSMutableDictionary dictionary];
for (NSDictionary* d in chat)
[newDict setValue:d[#"Value"][#"Value"] forKey:d[#"Key"]];
Now you can use the newDict.
NSLog(#"chatId: %#", [newDict valueForKey:#"chatId"]);
I have a NSArray containing multiple NSDictionary object and this NSDictionary again has one array of some NSStrings/NSNumbers...
This NSArray looks like below...
(
{
"bins_arr" = (
531662,
549177,
540165,
546616,
549777,
549778,
549779,
532663,
549852,
529495,
532662,
529117,
533890,
544170,
554619,
542418,
540175,
552137,
542531,
542556,
552093,
540531,
552790,
541497,
554637,
526421,
431921,
412800,
431922,
464558,
508159,
456822,
450900,
508126,
508125,
517700,
430463,
414746,
461797,
438628,
461796,
510460,
520386,
421175,
455038,
524133,
518936,
455390,
405450,
456407,
438587,
405451,
493714,
549149
);
"issuing_School" = ABCDEF;
status = 0;
title = ABCDEF;
},
{
"bins_arr" = (
429393,
416644,
416645,
416643,
416646,
436390,
436389,
436388,
470613,
524253,
428306,
489604,
478893,
414767,
428348,
469645,
421493,
470614,
543705
);
"issuing_School" = PQRS;
status = 0;
title = "PQRS";
},
{
"bins_arr" = (
422316,
421560,
483541
);
"issuing_School" = TCSB;
status = 0;
title = "TCSB";
}
)
Now I need to find out a given NString/NSNumber inside the NSArray, if it gets found I need to fine corresponding issuing_School value as well, for example If I find 461797 so it should search it and find that issuing_School of this is PQRS.
One way of doing it is to get the each NSArray inside NSArray-->NSDictionary and loop through the whole NSArray and match the given number with the number present and in the NSArray, but I don't want this search since this NSArray have so may object of NSDictionary and all NSDictionary object again have big NSArray.
Can Any one suggest me some awesome view to achieve this.
Thanks in Advance.
Turn your arrays into sets.
NSArray* array = ...;
NSSet* set = [[NSSet alloc] initWithArray:array];
if ([set containsObject:aNumber]) ...
No loop involved. Constant time no matter how many elements in the set.
I have created an NSDictionary named "myData"
which contains the following JSON response:
{
listInfo = (
{
date = 1392157366000;
dateAsString = "02/11/2014 22:22:46";
id = 6;
address = 542160e0000c;
myLevel = 13;
},
{
date = 1392155568000;
dateAsString = "02/11/2014 21:52:48";
id = 5;
address = 542160e0000c;
myLevel = 13;
}
);
}
I need to retrieve each of the [dateAsString] key/value pairs.
I've tried: NSString *dateAsString=[[myData valueForKeyPath:#"dateAsString"][0] objectForKey:#"myData"]; without any luck.
Any suggestions are greatly appreciated.
I think this will work:
NSArray* dateStringArray = [listInfo valueForKeyPath:#"#unionOfObjects.dateAsString"]
I believe it will give you an array of strings. If you need to stuff that back in a dictionary, that should be fairly easy.
It's not clear what your "myData" looks like... so I used the listInfo array of dicts shown.