Adding a value and key into an NSMutableArray - Objc - ios

I've read and tried a dozen or more variants of my own question, but still need some help please.
I have a large existing array, and I want to add a new object (key and value) to each record.
This is an element in the incoming array:
{
"trip_id": 65,
"arrival_time": "08:56:08",
"departure_time": "08:56:08",
"stop_id": 1161,
"stop_sequence": 8,
"stop_headsign": 0
},
This is what I want to achieve:
{
"trip_id": 65,
"arrival_time": "08:56:08",
"departure_time": "08:56:08",
"stop_id": 1161,
"stop_name": "a stop name",
"stop_sequence": 8,
"stop_headsign": 0
},
This is my code so far -- the commented lines are other attempts:
NSString *nameKey = #"stop_name";
int i=0;
for (i=0; i<stopTimesArray.count; i++) {
NSNumber *stopTimesId = [stopTimesArray[i] valueForKey:#"stop_id"];
int j=0;
for (j=0; j<stopArray.count; j++) {
NSNumber *stopId = [stopArray[j] valueForKey:#"stop_id"];
if (stopId == stopTimesId) {
NSString *stopNameString = [stopArray[j] valueForKey:#"stop_name"];
NSLog(#"stopNameString: %#", stopNameString);
[outgoingStopTimesDictionary setObject:stopNameString forKey:#"stop_name"];
//[outgoingStopTimesArray addObject:outgoingStopTimesDictionary];
//[outgoingStopTimesArray addObjectsFromArray:stopTimesArray[i]];
//[stopTimesArray[i] addObject:#{#"stop_name":stopNameString}];
//[stopTimesArray[i] addObject:#{#"stop_name":stopNameString}];
[stopTimesArray[i] addObject: outgoingStopTimesDictionary];
}
}
}
//NSLog(#"outgoingStopTimesArray: %#", outgoingStopTimesArray);
//NSLog(#"outgoingStopTimesDictionary: %#", outgoingStopTimesDictionary);
//NSLog(#"stopTimesArray: %#", stopTimesArray);
The error I am getting with approach is:
stopNameString: S Monroe Street, NB # 18th Street S, NS
[__NSCFDictionary addObject:]: unrecognized selector sent to instance 0x7fd7f2c22760
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary addObject:]: unrecognized selector sent to instance 0x7fd7f2c22760'
I'm either getting a null dictionary, or an unrecognised object exception when I try to add the dictionary to my array. Please point me to a working answer, and I'll delete my question.

It appears that your goal is to add one new key/value pair to the dictionary at stopTimesArray[i]. Here's your code all cleaned up with what I believe you need:
for (NSMutableDictionary *stopTimesDictionary in stopTimesArray) {
NSNumber *stopTimesId = stopTimesDictionary[#"stop_id"];
for (NSDictionary *stopDictionary in stopArray) {
NSNumber *stopId = stopDictionary[#"stop_id"];
if ([stopTimesId isEqual:stopId]) {
NSString *stopNameString = stopDictionary[#"stop_name"];
stopTimesDictionary[#"stop_name"] = stopNameString;
// Uncomment the following line if "stop_id" is unique within the "stopArray"
// break;
}
}
}
Since it seems your stopTimesArray contains immutable dictionaries, the above code won't work as written. Here is a solution that deals with that:
for (NSInteger i = 0; i < stopTimesArray.count; i++) {
NSDictionary *stopTimeDictionary = stopTimesArray[i];
NSNumber *stopTimesId = stopTimesDictionary[#"stop_id"];
for (NSDictionary *stopDictionary in stopArray) {
NSNumber *stopId = stopDictionary[#"stop_id"];
if ([stopTimesId isEqual:stopId]) {
NSString *stopNameString = stopDictionary[#"stop_name"];
NSMutableDictionary *tempDict = [stopTimesDictionary mutableCopy];
tempDict[#"stop_name"] = stopNameString;
[stopTimesArray replaceObjectAtIndex:i withObject:tempDict];
// Uncomment the following line if "stop_id" is unique within the "stopArray"
// break;
}
}
}

dictTo=[NSDictionary new];
dictTo =
#{
#"vPLocationLat" : [NSString stringWithFormat:#"%#",[[[[json valueForKey:#"result"] valueForKey:#"geometry"] valueForKey:#"location"] valueForKey:#"lat"]],
#"vPLocationLong" : [NSString stringWithFormat:#"%#",[[[[json valueForKey:#"result"] valueForKey:#"geometry"] valueForKey:#"location"] valueForKey:#"lng"]]
};
arrLocationList =[NSMutableArray new];
arrLocationList =[dictTo[#"data"] mutableCopy];
another Solution
-> Try to implement your Code as per in given Code
NSMutableArray* newArray = [NSMutableArray array];
NSArray* oldArray = outerDictionary[#"scores"];
for (NSDictionary* dictEntry in oldArray) {
NSString* leagueCode = dictEntry[#"league_code"];
if ([leagueCode isEqualToString #"epl"]) {
[newArray addObject:dictEntry];
}
}
Another one Solution
Try something like this.
Assume your array is called array and yourNewNameString is your new value for name
for(NSMutableDictionary *dict in array){
if([[dict objectForKey:#"id"]integerValue]==5){
[dict setObject:yourNewNameString forKey#"name"];
}
}
edit This is assuming you initialized your array with NSMutableDictionarys (Not just NSDictionarys)

//You can create dictionary and add it into NSMutableArray Object Like..
NSMutableArray *arr = [[NSMutableArray alloc] init];
NSDictionary *inventory = #{
#"Mercedes-Benz SLK250" : [NSNumber numberWithInt:13],
#"Mercedes-Benz E350" : [NSNumber numberWithInt:22],
#"BMW M3 Coupe" : [NSNumber numberWithInt:19],
#"BMW X6" : [NSNumber numberWithInt:16],
};
[arr addObject:inventory];
//You can access using key like...
NSString *strForBMWX6 = [[arr objectAtIndex:0] valueForKey:#"BMW X6"];
// in your case you just miss objectAtIndex:j

First, thanks #rmaddy.
I modified his answer a bit, but his was basically correct.
My final code looks like this:
for (NSInteger i = 0; i < stopTimesArray.count; i++) {
NSDictionary *stopTimesDictionary = stopTimesArray[i];
NSNumber *stopTimesId = stopTimesDictionary[#"stop_id"];
for (NSDictionary *stopDictionary in stopArray) {
NSNumber *stopId = stopDictionary[#"stop_id"];
if ([stopTimesId isEqual:stopId]) {
NSString *stopNameString = stopDictionary[#"stop_name"];
NSMutableDictionary *tempDict = [stopTimesDictionary mutableCopy];
tempDict[#"stop_name"] = stopNameString;
[outgoingStopTimesArray addObject:tempDict];
break;
}
}
}

Related

How to print the contents of NSSet?

I query and get a NSSet which contains customer address from web. Since I'm new to objective c development I don't know how to get country,zip code etc from that set.So I followed Objective-C How to print NSSet on one line (no trailing comma / space) but my output is in the form of object "0x7f99997b7a50". How can I print all the strings in the set? Thanks in advance.
I tried like this
NSArray *ar = [customer.addresses allObjects];
for (int i = 0; i<ar.count; i++)
{
NSLog(#"arr %#",ar[i]);
}
But the output is arr:
<BUYAddress: 0x7fd451f6e050>
If you have a custom object, you may need to override description
Without overriding:
-(void) testCustomObjects
{
CustomObject *co1 = [[CustomObject alloc] init];
co1.name = #"James Webster";
co1.jobTitle = #"Code Monkey";
CustomObject *co2 = [[CustomObject alloc] init];
co2.name = #"Holly T Canine";
co2.jobTitle = #"Pet Dog";
NSSet *set = [NSSet setWithObjects:co1, co2, nil];
NSLog(#"%#", [set allObjects]);
}
produces:
2016-12-02 11:45:55.342 Playground[95359:4188387] (
"<CustomObject: 0x600000037a20>",
"<CustomObject: 0x60000003ae20>"
)
However, if I override the description method in my CustomObject class:
-(NSString*) description
{
return [NSString stringWithFormat:#"%# (%#)", self.name, self.jobTitle];
}
I get the following:
(
"Holly T Canine (Pet Dog)",
"James Webster (Code Monkey)"
)
If for whatever reason, you can't add a description method, you'd just have to access the relevant parts of the object; something like the following:
NSArray *ar = [customer.addresses allObjects];
for (int i = 0; i<ar.count; i++)
{
NSLog(#"arr %# (%#)",ar[i].name, ar[i].address);
}
I've had a little look at the library you're using. Try the following:
for (BUYAddress *address in customer.addresses)
{
NSLog(#"Address: %#, %#, %#", address.address1, address.address2, address.city);
}
Consider NSSet below,
NSSet *theNSSet = [NSSet setWithObjects:#"Chennai",#"Mumbai",#"Delhi", nil];
Convert it into NSArray using
NSArray *array = [theNSSet allObjects]; // theNSSet is replaced with your NSSet id
Then print it like
NSLog(#"%#",array);
Output im getting
(
Chennai,
Delhi,
Mumbai
)
In your case:
- (NSMutableSet *)addressesSet {
[self willAccessValueForKey:#"addresses"];
NSMutableSet *result = (NSMutableSet *)[self mutableSetValueForKey:#"addresses"];
[self didAccessValueForKey:#"addresses"];
NSLog(#"%#",[result allObjects]); // printing the nsset
return result;
}

Separate a String By Semicolon

I am using following code to separate a string into multiple strings and getting an error
NSArray *arr = [randomStr componentsSeparatedByString:#";"];
Error:
-[__NSDictionaryM componentsSeparatedByString:]: unrecognized selector sent to instance 0x1758f230
-[__NSDictionaryM componentsSeparatedByString:]: unrecognized selector sent to instance 0x1758f230
This is my Sample Data
NSArray *data = {
{
name = "name1";
address = "RWP";
ID = 0;
},
{
name = "name2";
address = "RWP";
ID = 1;
},
{
name = "name3";
address = "RWP";
ID = 2;
},}
NSString *randomStr = data[0];
What's wrong in my code
You have an array of dictionaries, not strings. There is nothing to split.
You want something like this:
NSDictionary *dict = data[0];
NSString *name = dict[#"name"];
NSString *address = dict[#"address"];
You have to be sure randomStr as a NSString.
You can check like
if ([randomStr isKindOfClass:[NSString Class]]) {
NSArray *arr = [randomStr componentsSeparatedByString:#";"];
}
It sounds like the randomStr variable is an MutableDictionary. Thats why its not working.
here is my Test:
NSString *foo = #"BAR;FOO;VAR";
NSArray *arr = [foo componentsSeparatedByString:#";"];
NSLog(#"%#", arr);
Thise Logs:
BAR,
FOO,
VAR
EDIT:
Dictionary to array:
NSMutableDictionary *dict = #{#"aKey1" :#"BAR",
#"aKey2" :#"FOO",
#"aKey3" :#"VAR"}.mutableCopy;
NSMutableArray *array = [[NSMutableArray alloc] init];
for (NSString *key in dict) {
[array addObject:dict[key]];
}
NSLog(#"%#",array);
This Logs:
BAR,
FOO,
VAR

How to iterate & retrieve values from NSArray of NSArrays of NSDictionaries

I'm stumpped on how iterate and get values for an Array of Arrays of NSDictionaries (different classes/entities). Here's what I'm currently doing:
1) Constructing two separate arrays of NSDictionaries (different entities)
2) Combining both arrays with:
NSMutableArray *combinedArrayofDicts = [[NSMutableArray alloc] initWithObjects: sizesArrayOfDicts, wishListArrayOfDicts , nil];
3) Then archive combinedArrayofDicts :
NSData *dataToSend = [NSKeyedArchiver archivedDataWithRootObject:combinedArrayofDicts];
4) Transmit over GameKit
[self.session sendDataToAllPiers:dataToSend withDataMode: GKSendDataReliable error:nil];
5) How would I manage traversing thru this array on the receiving end? I want to fetch values by for each class which is key'ed by classname:
Here's how it looks via NSLog (2 Sizes Dicts, and 1 Wishlist Dict)
Printing description of receivedArray:
<__NSArrayM 0xbc65eb0>(
<__NSArrayM 0xbc651f0>(
{
classname = Sizes;
displayOrder = 0;
share = 1;
sizeType = Neck;
value = "13\" or 33 (cm)";
},
{
classname = Sizes;
displayOrder = 0;
share = 1;
sizeType = Sleeve;
value = "34\" or 86 (cm)";
}
)
,
<__NSArrayM 0xbc65e80>(
{
classname = Wishlist;
detail = "";
displayOrder = 0;
imageString = "";
latitude = "30.33216666666667";
link = "http://maps.google.com/maps?q=loc:30.332,-81.41";
longitude = "-81.40949999999999";
name = bass;
share = 1;
store = "";
}
)
)
(lldb)
In my for loop I'm issuing this:
NSString *value = [dict objectForKey:#"classname"];
and get an exception:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM objectForKey:]:
unrecognized selector sent to instance 0xbc651f0'
Is this frowned upon as far as mixing object types in arrays of arrays?
#Will guided me to the answer with the right construct.. Here's the final answer:
NSArray *receivedArray;
if(receivedArray.count>0){
NSArray *combinedArrayofDicts = [receivedArray objectAtIndex:0];
if(combinedArrayofDicts.count>=2){
NSArray *sizesArray = [receivedArray objectAtIndex:0]; // Reference original received array
for(NSDictionary *sizeDict in sizesArray){
NSLog(#"%#",sizeDict);
}
NSArray *wishListArray = [receivedArray objectAtIndex:1]; // Reference original received array
for(NSDictionary *wishDict in wishListArray){
NSLog(#"%#",wishDict);
}
}
}
for fetching the required dictionaries use the following code,
Assume receivedArray as the array receive from Game center
NSArray *receivedArray;
if(receivedArray.count>0){
NSArray *combinedArrayofDicts = [receivedArray objectAtIndex:0];
if(combinedArrayofDicts.count>=2){
NSArray *sizesArray = [combinedArrayofDicts objectAtIndex:0];
for(NSDictionary *sizeDict in sizesArray){
NSLog(#"%#",sizeDict);
}
NSArray *wishListArray = [combinedArrayofDicts objectAtIndex:1];
for(NSDictionary *wishDict in wishListArray){
NSLog(#"%#",wishDict);
}
}
}
how iterate and get values for an Array of Arrays of NSDictionaries
As you said you have array of array of dictionaries, your current code will not retrive value of class name.
Your return values are in NSArray not in NSDictionary
So you need to do something like,
NSString *value = [returnArray[0][0] objectForKey:#"classname"];
You can iterate and get values like,
for (int i = 0; i < [returnArray count]; i++) {
for (int j = 0; j < [returnArray[i] count]; j++) {
NSDictionary *dict = (NSDictionary*)returnArray[i][j];
NSLog(#"%# ...",[dict objectForKey:#"classname"]);
}
}
Perhaps you can try:
NSString *value = [NSString stringWithFormat:#"%#",[dict objectForKey:#"classname"]];
By the looks of your output, I don't think "Sizes" is a string.

-[__NSDictionaryI setObject:forKey:]: unrecognized selector sent to instance 0x91da0f0

when i set the value in nsmutabledictionary then given error show in image below....
here my code for setvalue in nsmutabledictionary
NSMutableArray *countArray=[[NSMutableArray alloc] init];
for (int i=0;i<artistName.count;i++)
{
int count=0;
NSMutableDictionary *dir1=[artistName objectAtIndex:i];
NSString *artist1=[dir1 objectForKey:#"SONG_ARTIST"];
for (int j=0;j<CurrentPlayingSong.count;j++)
{
NSDictionary *dir2=[CurrentPlayingSong objectAtIndex:j];
NSString *artist2=[dir2 objectForKey:#"SONG_ARTIST"];
if ([artist2 isEqualToString:artist1])
{
count++;
}
}
NSString *Size=[[NSString alloc] initWithFormat:#"%d",count];
[dir1 setObject:Size forKey:#"SIZE"];
[countArray addObject:dir1];
}
return countArray;
this NSMutableDictionary *dir1=[artistName objectAtIndex:i]; returns a NSDictionary object which turns your dir1 to the same type.
best way is to do something like this:
NSMutableDictionary *dir1=[NSMutableDictionary dictionaryWithDictionary:[artistName objectAtIndex:i]];
or
NSMutableDictionary *dir1 = [artistName[i] mutableCopy];
This will ensure that dir1 will always be NSMutableDictionary.
hope this helps

I've got strange output from 'componentsSeparatedByString' method of NSString

I want to store the array of NSDictionary to a file. So I write a function to convert from NSArray to NSString. But I got a very strange problem. Here is my code.
+ (NSArray *)arrayForString:(NSString*)dataString
{
NSArray* stringArray = [dataString componentsSeparatedByString:ROW_SEPARATOR];
NSLog(#"%#", stringArray);
NSMutableArray* dictionaryArray = [[NSMutableArray alloc] initWithCapacity:0];
for (int i = 0; i < [stringArray count]; i++)
{
NSString* string = [stringArray objectAtIndex:i];
NSLog(#"%#", string);
NSArray* subStrings = [string componentsSeparatedByString:COLUMN_SEPARATOR];
NSDictionary* dic = [[NSDictionary alloc] initWithObjectsAndKeys:[subStrings objectAtIndex:0], PHOTO_NAME, [NSNumber numberWithUnsignedInt:[[subStrings objectAtIndex:1] unsignedIntValue]], PHOTO_SEQ_NO, nil];
[dictionaryArray addObject:dic];
}
return dictionaryArray;
}
Here is the log:
2012-05-05 23:57:35.113 SoundRecognizer[147:707] (
"new Photo/0",
"new Photo/1"
)
2012-05-05 23:57:35.118 SoundRecognizer[147:707] new Photo/0
2012-05-05 23:57:35.123 SoundRecognizer[147:707] -[__NSCFString unsignedIntValue]: unrecognized selector sent to instance 0x1d18c0
How do I get a #"-" from this following array?!
2012-05-05 23:57:35.113 SoundRecognizer[147:707] (
"new Photo/0",
"new Photo/1"
)
NSString doesn't have an unsignedIntValue method. Use intValue instead. But I'm not sure of the point of all this - you can write an array of dictionaries straight to a file anyway (as long as they only contain property list types) using writeToFile: atomically:.

Resources