How to add arrays for key and object in NSDictionary - ios

I have 2 arrays. Array A arrayA[0] contains {a,b,c,d,e...} and Array B arrayB[0] contains {a,b,c...}. And both arrays are mutable and have many objects. In NSMutableDictionary for each element in Array A (taken as key) should store entire Array B.
For example:
(key value)Array A[0] have entire (object value)Array B(0...200)
(key value)Array A[1] have entire (object value)Array B(0...200)
(key value)Array A[2] have entire (object value)Array B(0...200)
My code:
for (int i=0; i<100; i++)
{
[someDictionary setObject:arrayB forKey:arrayA[i]];
}
this doesn't work and i tried this too :
[someDictionary initWithObjects:arrayB forKeys:arrayA[i]]

You should use NSString for storing key in key-value pair. So i would recommend
for (int i=0; i<100; i++) {
NSString *str=(NSString *)arrayA[i];
[someDictionary setObject:arrayB forKey:str];
}

Your code looks fine in principle. Obviously being fixed to 100 elements is not nice, so I'd write
for (id key in self.arrayA)
[someDictionary setObject:self.arrayB forKey:key];

Try this answer. I don't know brother whether I am understanding your question correctly or wrongly.
Try my code:
NSMutableArray *tempA=[NSMutableArray array];
NSMutableArray *tempB=[NSMutableArray array];
for (int a = 0; a < 100; a++)
{
[tempA addObject:[NSString stringWithFormat:#"%d",a]];
}
NSMutableArray *dataArray=[NSMutableArray array];
NSMutableDictionary *dict;
for (int i = 0; i < [tempA count]; i++)
{
for (int a = 0; a < 100; a++)
{
dict=[NSMutableDictionary dictionary];
NSString* localTemp=[NSString stringWithFormat:#"key-%#",[tempA objectAtIndex:i]];
[tempB addObject:[NSString stringWithFormat:#"%d",a]];
id object=[tempB objectAtIndex:a];
[dict setObject:object forKey:localTemp];
[dataArray addObject:dict];
}
}
NSLog(#"Dictionary is---->%#",dataArray);

NSArray *arrayA = [NSArray arrayWithObjects:#"1",#"2", nil];
NSArray *arrayB = [NSArray arrayWithObjects:#"3",#"4", nil];
NSMutableDictionary *temp = [[NSMutableDictionary alloc]init];
for(int i =0 ; i<[arrayA count];i++)
{
[temp setObject:arrayB forKey:[arrayA objectAtIndex:i]];
}

Related

Count in multi-dimensional array

How would you count this array?
NSArray *sortThisArray = #[#{#"numbers":#[#"One",#"Two"]},
#{#"numbers":#[#"Two",#"One"]},
#{#"numbers":#[#"One",#"Two",#"Three"]},
#{#"numbers":#[#"One",#"Two",#"Three"]},
#{#"numbers":#[#"One",#"Two",#"Three",#"Four"]},
];
The desired result would then be:
NSArray *sortedArray = #[#{#"numbers":#[#"One",#"Two"],
#"occures":#(2)},
#{#"numbers":#[#"One",#"Two",#"Three"],
#"occures":#(2)},
#{#"numbers":#[#"One",#"Two",#"Three",#"Four"],
#"occures":#(1)},
];
I've tried using NSCountedSet and countForObject, but the results are inaccurate. It seems to only count the arrays that are exactly the same. In other words, the array with #[#"Two",#"One"] gets ignored because its not 100% equal to #[#"One",#"Two"], even though they have the same objects and same count.
This should work. You have to have a consistent way to compare your arrays (either sorting like in this example or by moving the NSArray to NSSet).
NSMutableDictionary<NSArray<NSString *> *, NSNumber *> *valueCount = [NSMutableDictionary dictionary];
for (NSDictionary<NSString *, NSArray<NSString *> *> *value in sortThisArray) {
NSArray<NSString *> *numberStrings = [value[#"numbers"] sortedArrayUsingSelector:#selector(compare:)];
valueCount[numberStrings] = #(valueCount[numberStrings].integerValue + 1);
}
NSMutableArray *sortedArray = [NSMutableArray arrayWithCapacity:valueCount.count];
for (NSArray<NSString *> *key in valueCount) {
[sortedArray addObject:#{#"numbers": key, #"occures": valueCount[key]}];
}
May be something like this:
NSMutableArray *mArray = [NSMutableArray arrayWithArray:sortThisArray];
NSMutableArray *result = [[NSMutableArray alloc] init];
while ([mArray count]) {
NSDictionary *obj = [mArray firstObject];
int count = 1;
for (int i=1; i<[mArray count]; i++) {
NSDictionary *sObj = [mArray objectAtIndex:i];
if ([[sObj objectForKey:#"numbers"] count] == [[obj objectForKey:#"numbers"] count]) {
BOOL increase = YES;
for (int j=0; j<[[obj objectForKey:#"numbers"] count]; j++) {
if (![[sObj objectForKey:#"numbers"] containsObject:[[obj objectForKey:#"numbers"] objectAtIndex:j]]) {
increase = NO;
}
}
if (increase) {
count++;
[mArray removeObjectAtIndex:i];
}
}
}
[mArray removeObjectAtIndex:0];
[result addObject:#{#"numbers":obj, #"occurrs":[NSNumber numberWithInteger:count]}];
}
*Code is not tested

Remove array elements and add them at the same index iOS

I am sorting an array.
There are three types of elements in the array.
1. featured
2. organic and
3. claimed.
Among them, I want to sort only organic elements and keep the featured and claimed elements at their own index.
Below is my code in which, I am extracting the claimed and featured indices in a dictionary as key being the index and value is the array element.
//Initialization
NSMutableArray *sortedArray = nil;
NSMutableDictionary *tempFeaturedDictionary = [[NSMutableDictionary alloc]init];
NSMutableDictionary *tempClaimedDictionary = [[NSMutableDictionary alloc]init];
NSMutableArray *tempOrganicArray = [[NSMutableArray alloc]init];
for (int i = 0; i < array.count; i++) {
DRListing *isFeaturedObj = (DRListing*)[array objectAtIndex:i];
if (isFeaturedObj.featured) {
[tempFeaturedDictionary setObject:isFeaturedObj forKey:[#(i)stringValue]];
}else if (isFeaturedObj.claimed)
{
[tempClaimedDictionary setObject:isFeaturedObj forKey:[#(i)stringValue]];
}else
[tempOrganicArray addObject:isFeaturedObj];
}
Again I am adding the claimed and featured back to their original indices after sorting as:
sortedArray = [NSMutableArray arrayWithArray:[tempOrganicArray sortedArrayUsingDescriptors:sortDescriptorsArray]];
for (int i = 0; i<sortedArray.count; i++) {
for (NSString *key in tempFeaturedDictionary) {
if ( [[#(i)stringValue] isEqualToString: key] ) {
[sortedArray insertObject:[tempFeaturedDictionary objectForKey:[#(i)stringValue]] atIndex:i];
}}
for (NSString *key in tempClaimedDictionary) {
if ([[#(i)stringValue]isEqualToString:key ]) {
[sortedArray insertObject:[tempClaimedDictionary objectForKey:[#(i)stringValue]] atIndex:i];
}
}
}
The code works good. Except there is claimed/(and)featured elements at the last index of the 'array'. Because the 'sortedArray' index remains less than the 'array.count' in this scenario.
Thanks in advance.
Update -
I receive response array of type:
[{featured1 featured2}, {organic1, organic2..}, {claimed1}, {featured11, featured12}, {organic11, organic12..}, {claimed2}, ..]
and I am allowed to sort only organic elements within this array. Featured and claimed should not loose their original index position.
I would iterate through the array, extracting the organics to sort. Then sort your organic array. Then iterate through the original array taking either the element from the original array or an element from the sorted organics array as appropriate.
NSMutableArray *organicsArray = [NSMutableArray new];
for (int i = 0; i < array.count; i++) {
DRListing *isFeaturedObj = (DRListing*)array[i];
if ((!isFeaturedObj.featured) && (!isFeaturedObj.claimed)) {
[organicsArray addObject:isFeaturedObj];
}
}
NSMutableArray *sortedOrganicsArray = [[organicsArray sortedArrayUsingDescriptors:sortDescriptorsArray] mutableCopy];
NSMutableArray *outputArray = [NSMutableArray new];
for (int i = 0; i < array.count; i++) {
DRListing *isFeaturedObj = (DRListing*)array[i];
if ((!isFeaturedObj.featured) && (!isFeaturedObj.claimed)) {
[outputArray addObject:sortedOrganicsArray[0]];
[sortedOrganicsArray removeObjectAtIndex:0];
} else {
[outputArray addObject:isFeaturedObject];
}
}
You could possibly make it a little more efficient if you reversed your sort order for the organics array since then you could say
[outputArray addObject:[sortedOrganicsArray lastObject]];
[sortedOrganicsArray removeLastObject];
But if your array isn't particularly large then the performance improvement will probably be negligible.
Maybe this is an alternative:
NSMutableArray *organics = [NSMutableArray new];
NSMutableArray *others = [NSMutableArray new];
for (DRListing *isFeaturedObj in array) {
if (isFeaturedObj.organic) {
[organics addObject:isFeaturedObj];
} else {
[others addObject:isFeaturedObj];
}
}
NSMutableArray *sorted = [NSMutableArray alloc]initWithObjects:organics,others, nil];
You can take the first 2 functions. The others are what I used for testing.
- (DRListing *)getNextObjectFromArray:(NSArray *)array WithStartingIndex:(int)index
{
for (int i=index; i<array.count; i++) {
DRListing *obj = (DRListing*)[array objectAtIndex:i];
if (!obj.featured && !obj.claimed)
{
return obj;
}
}
return nil;
}
- (void)sortArray:(NSMutableArray *)array
{
for (int pass = 0; pass<array.count-1; pass++) {
for (int i=0; i<array.count-1; i++) {
DRListing *obj = [self getNextObjectFromArray:array WithStartingIndex:i];
int foundIndex = (int)[array indexOfObject:obj];
DRListing *obj2 = [self getNextObjectFromArray:array WithStartingIndex:foundIndex+1];
int foundIndex2 = (int)[array indexOfObject:obj2];
if (obj!=nil && obj2 !=nil) {
if (obj.value >= obj2.value) {
[array exchangeObjectAtIndex:foundIndex withObjectAtIndex:foundIndex2];
}
i = foundIndex;
}
}
}
NSLog(#"Sorted Data: %#",array);
}
- (NSMutableArray *)testData
{
NSMutableArray *array = [NSMutableArray new];
for (int i=0; i<20; i++) {
DRListing *obj = [DRListing new];
obj.featured = i*i%2;
obj.claimed = i%2;
obj.value = i*3%10;
[array addObject:obj];
}
NSLog(#"Test Data: %#",array);
return array;
}
#interface DRListing : NSObject
#property (nonatomic) BOOL featured;
#property (nonatomic) BOOL claimed;
#property (nonatomic) int value;
#end

Adding items to a NSMutableArray - Logic issue

I have 5 animal objects and i trying to save it in a NSMutableDIctionary. However, according to my code below, only the last animal gets saved in the NSMutableDIctionary.
I don't think i am looping it correctly.
for(int i = 0; i < animalCount; i++) {
[allContacts setObject:name forKey:#"name"];
[allContacts setObject:age forKey:#"age"];
[allContacts setObject:gender forKey:#"gender"];
}
The output of the above displays as follows: (Only the last animal object gets displayed)
{
name = fish;
age = 6;
gender = "female";
}
How i want is that, all five animal objects to be saved in the NSMutableDIctionary so i can display them in a UITableView.
{
name = "cow";
age = 4;
gender = "male";
},
{
name = "dog";
age = 15;
gender = "male";
},
{
name = "fish";
age = 6;
gender = "female";
}
Key of NSMutableDictionary is unique.
What you want do is build an Array and every object of this Array is a Dictionary
NSMutableArray * contentsArray = [[NSMutableArray alloc] init];
for(int i = 0; i < animalCount; i++) {
NSMutableDictionary * allContacts = [[NSMutableDictionary alloc] init];
[allContacts setObject:name forKey:#"name"];
[allContacts setObject:age forKey:#"age"];
[allContacts setObject:gender forKey:#"gender"];
[contentsArray addObject:allContacts];
}
First create a NSMutableArray in order to loop and create the dictionaries. Then create individual dictionaries.
NSMutableArray *outputArray = [NSMutableArray array];
for ( int i=0; i< animalCount; i++) {
NSMutableDictionary *internalDictionary = [NSMutableDictionary dictionary];
[internalDictionary setObject:[nameArray objectAtIndex: i] forKey:#"name"];
[internalDictionary setObject:[ageArray objectAtIndex: i] forKey:#"age"];
[internalDictionary setObject:[genderArray objectAtIndex: i] forKey:#"gender"];
[outputArray addObject:internalDictionary];
}
NSLog(#"%#",outputArray);
Cheers!
You need an array of dictionaries, where your keys are constants (name, age, gender) and your values should be considered from their index (you'll need an array of names, ages, and genders), unless you'll have a lot of similar dictionaries:
NSMutableArray * contentsArray = [NSMutableArray new];
for(int i = 0; i < animalCount; i++) {
NSMutableDictionary * allContacts = [[NSMutableDictionary alloc] init];
[allContacts setObject:arrNames[i] forKey:#"name"];
[allContacts setObject:arrAges[i] forKey:#"age"];
[allContacts setObject:arrGenders[i] forKey:#"gender"];
[contentsArray addObject:allContacts];
}
or in modern objective c (simpler & shorter):
NSMutableArray *contentsArray = [NSMutableArray new];
for(int i = 0; i < animalCount; i++) {
[contentsArray addObject:#{#"name" : arrNames[i],
#"age" : arrAges[i],
#"gender" : arrGenders[i]}];
}
The reason is every time you are looping, you are updating the keys of your MSMutableDictionary, but you are not saving it anywhere.
Just take an NSMutableArray and save your dictionaries every time you update it.
So, first initialise the array outside the loop-
NSMutableArray *allContactsArray = [[NSMutableArray alloc] initWithCapacity: animalCount];
Now, run the loop, and save the dictionary every time before you loose it.
for(int i = 0; i < animalCount; i++) {
[allContacts setValue:name forKey:#"name"];
[allContacts setValue:age forKey:#"age"];
[allContacts setValue:gender forKey:#"gender"];
//save the allContacts dictionary in the array
[allContactsArray insertObject:allContacts atIndex:i];
}
This way you also you at what index you are saving your dictionary while adding.
I think you are mistaken. You should be saving dictionaries into an array, to populate tableview.
NSMutableArray *animals = [NSMutableArray array];
for(int i = 0; i < animalCount; i++) {
NSDictionary *dict = #{#"name" : name, #"age" : age, #"gender" : gender};
[animals addObject:dict];
}
Access in cellForRowAtIndexPath using:
NSDictionary *dict = animals[indexPath.row];
cell.textLabel.text = dict[#"name"];

NSMutableArray (1 dim) from NSArray (2dim)

I want to make 1 array that will hold all of the other arrays objects and will look like this
("052-6224754","03-6475075","02-6753231")
my code is:
-(NSMutableArray*) getRecepientsPhones
{
NSMutableArray* phones = [[NSMutableArray alloc]init];
//scroll all choosed contacts and retrieve phones to nsstring
if([recepientsFromContacts count]>0)
for (int i=0; i<[recepientsFromContacts count]; i++)
{
NSMutableArray* tempArray = [[NSMutableArray alloc]init];
if(![[[recepientsFromContacts objectAtIndex:i]objectForKey:#"CPhones"]isKindOfClass:[NSNull class]])
{
[tempArray addObject:[[recepientsFromContacts objectAtIndex:i]objectForKey:#"CPhones"]];
for(int j = 0; j<[tempArray count];j++)
{
[phones addObject:[tempArray objectAtIndex:j]];
}
}
}
//lets fetch from that contact
if([personRecepient count]>0)
{
if(![[personRecepient objectForKey:#"CellPhone"]isKindOfClass:[NSNull class]])
[phones addObject:[personRecepient objectForKey:#"CellPhone"]];
}
NSLog(#"%#",phones);
return phones;
}
[[recepientsFromContacts objectAtIndex:i]objectForKey:#"CPhones"]
is 1 or more dimension array (it is array of phone numbers per person , person can have more than 1 number)
example: ("052-6224754","03-6475075")
but my function returns
("052-6224754","03-6475075"),("02-6753231")
which is not good , what should I do to make it 1 array
("052-6224754","03-6475075","02-6753231")
You should change the line
[phones addObject:[tempArray objectAtIndex:j]];
to
[phones addObjectsFromArray:[tempArray objectAtIndex:j]];
This should result in a flattened array of phone numbers.
Then you should head over to codereview.stackexchange.com because there are several issues with your code fragment.
Edit: Here's a cleaned up version of the method:
- (NSArray *)recepientsPhoneNumbers
{
NSMutableArray* phoneNumbers = [NSMutableArray array];
for (NSDictionary *dict in _recepientsFromContacts)
{
id recipientPhoneNumbers = dict[#"CPhones"];
if (recipientPhoneNumbers != [NSNull null])
[phoneNumbers addObjectsFromArray:recipientPhoneNumbers];
}
id recipientPhoneNumbers = _personRecepient[#"CellPhone"];
if (recipientPhoneNumbers != [NSNull null])
[phoneNumbers addObjectsFromArray:recipientPhoneNumbers];
NSLog(#"%#", phoneNumbers);
return phoneNumbers;
}
I applied Cocoa coding conventions, so ivars are now prefixed with underscores.

Grouping the NSArray elements into NSMutableDictionary

I have an NSArray some thing like in the following format.
The group array is :
(
"Q-1-A1",
"Q-1-A9",
"Q-2-A1",
"Q-2-A5",
"Q-3-A1",
"Q-3-A8",
"Q-4-A1",
"Q-4-A4",
"Q-10-A2",
"Q-8-A2",
"Q-9-A2",
"Q-7-A1",
"Q-5-A2"
)
Now what i have to do is group the array elements some thing like this.
1 = ( "Q-1-A1","Q-1-A9")
2 = ("Q-2-A1","Q-2-A5",) ...
10 =("Q-10-A2")
can any one please help me how can i achieve this.
Thanks in advance.
Try
NSArray *array = #[#"Q-1-A1",
#"Q-1-A9",
#"Q-2-A1",
#"Q-2-A5",
#"Q-3-A1",
#"Q-3-A8",
#"Q-4-A1",
#"Q-4-A4",
#"Q-10-A2",
#"Q-8-A2",
#"Q-9-A2",
#"Q-7-A1",
#"Q-5-A2"];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
for (NSString *string in array) {
NSArray *components = [string componentsSeparatedByString:#"-"];
NSString *key = components[1];
NSMutableArray *tempArray = dictionary[key];
if (!tempArray) {
tempArray = [NSMutableArray array];
}
[tempArray addObject:string];
dictionary[key] = tempArray;
}
Create an NSMutableDictionary, then iterate through your 'group array'.
For each NSString object:
get the NSArray of componentsSeparatedByString:#"-"
use the second component to create a key and retrieve the object for that key from your mutable dictionary. If its nil then set it to an empty NSMutableArray.
add the original NSString to the mutable array.
Try this
NSArray *arrData =[[NSArray alloc]initWithObjects:#"Q-1-A1",#"Q-1-A9",#"Q-2-A1",#"Q-2-A5",#"Q-3-A1",#"Q-3-A8",#"Q-4-A1",#"Q-4-A4",#"Q-10-A2",#"Q-8-A2",#"Q-9-A2",#"Q-7-A1",#"Q-5-A2", nil ];
NSMutableDictionary *dictList = [[NSMutableDictionary alloc]init];
for (int i=0; i<[arrData count];i++) {
NSArray *arrItem = [[arrData objectAtIndex:i] componentsSeparatedByString:#"-"];
NSMutableArray *arrSplitedItems = [dictList valueForKey:[arrItem objectAtIndex:1]];
if (!arrSplitedItems) {
arrSplitedItems = [NSMutableArray array];
}
[arrSplitedItems addObject:[arrData objectAtIndex:i]];
[dictList setValue:arrSplitedItems forKey:[arrItem objectAtIndex:1]];
}
NSArray *sortedKeys =[dictList allKeys];
NSArray *sortedArray = [sortedKeys sortedArrayUsingComparator:^(id str1, id str2) {
return [((NSString *)str1) compare:((NSString *)str2) options:NSNumericSearch];
}];
for (int i=0; i<[sortedArray count]; i++) {
NSLog(#"%#",[dictList objectForKey:[sortedArray objectAtIndex:i]]);
}
listOfYourMainArray/// Its YOur main Array;
temArray = (NSArray *)listOfYourMainArray; // Add Your main array to `temArray`.
NSMutableDictionary *lastDic = [[NSMutableDictionary alloc] init]; /// YOu need to creat Dictionary for arrange your values.
for (int i = 0; i< listOfYourMainArray.count; i++)
{
for (int j = 0 ; j < temArray.count; j ++)
{
if (([[temArray objectAtIndex:j] rangeOfString:[NSString stringWithFormat:#"Q-%d", i] options:NSCaseInsensitiveSearch].location != NSNotFound))
{
[lastDic setValue:[temArray objectAtIndex:j] forKey:[NSString stringWithFormat:#"%d", i]];
}
}
}
NSLog(#"%#", lastDic)

Resources