I have a NSArray made out of numbers 1..50, which represents a table with columns & rows.
I need to reverse only the order of the columns, while keeping the order of the rows.
So for example:
0,1,2,3,4,5,6
7,8,9,9,10,11,12
has to be
6,5,4,3,2,1,0
12,11,10,9,8,7
Right now, i use a huge IF statement for that:
for (dd *d in dates[i]) {
if (tileNum==0) {
reversedTileNum = 6;
} else if (tileNum==1) {
reversedTileNum = 5;
}else if (tileNum==2) {
reversedTileNum = 4;
}else if (tileNum==3) {
reversedTileNum = 3;
}else if (tileNum==4) {
reversedTileNum = 2;
}else if (tileNum==5) {
reversedTileNum = 1;
} else if (tileNum==6) {
reversedTileNum = 0;
}
....
....
}
Here's a solution that should be easy to drop into any project. It involves two categories: one on NSMutableArray that provides a method to swap objects at two indices, and one on NSArray that provides the -arrayByReversingGroups: method. The idea is to swap the elements in pairs within a group, reversing the group. If number of elements in the array isn't an even multiple of groupSize, the extras at the end are left untouched.
The code presented here is a complete program, so you can see an example of using -arrayByReversingGroups: in the main() function.
#import <Foundation/Foundation.h>
#interface NSArray(Reversible)
-(NSArray*)arrayByReversingGroups:(int)groupSize;
#end
#interface NSMutableArray(Swappable)
-(void)swapObjectAtIndex:(int)first withObjectAtIndex:(int)second;
#end
#implementation NSArray(Reversible)
-(NSArray*)arrayByReversingGroups:(int)groupSize
{
NSMutableArray *newArray = [self mutableCopy];
// Iterate over the array in chunks of groupSize elements. i will be first index in
// the current chunk.
for (int i = 0; (i + groupSize) < [newArray count]; i += groupSize) {
// Iterate over the items in the current chunk, swapping the bth and
// (groupsize-b-1)th elements until they meet at groupsize/2.
for (int b = 0; b <= (groupSize / 2); b++) {
int first = i + b;
int second = i + groupSize - b - 1;
[newArray swapObjectAtIndex:first withObjectAtIndex:second];
}
}
return [newArray copy];
}
#end
#implementation NSMutableArray(Swappable)
-(void)swapObjectAtIndex:(int)first withObjectAtIndex:(int)second
{
id temp = [[self objectAtIndex:second] retain];
[self replaceObjectAtIndex:second withObject:[self objectAtIndex:first]];
[self replaceObjectAtIndex:first withObject:temp];
[temp release];
}
#end
int main (int argc, const char * argv[])
{
#autoreleasepool {
NSArray *array = [NSArray arrayWithObjects:
#"1", #"2", #"3", #"4", #"5", #"6", #"7", #"8", #"9", #"10", #"11", #"12", nil];
NSLog(#"Original: %#", array);
NSLog(#"Reversed: %#", [array arrayByReversingGroups:5]);
}
return 0;
}
I can give you the logic.. you will have to write the code...
First create a function where you pass in an array(here you will send in a row.) then in this function create a new tempeorary array and store all the values for that row in this column then overwrite the original array in reverse order from this new array and return this to the full matrix and store it in there ... hope it helps.
Related
I have a dictionary like:
{
dataTypes = (
{
dataType = "datatype1";
editable = 1;
maxValue = 300;
minValue = 0;
order = 1;
title = "Title 1";
type = numeric;
units = kg;
},
{
dataType = "datatype 2";
editable = 1;
maxValue = 300;
minValue = 0;
order = 2;
title = "title2";
type = numeric;
units = gm;
},
{
dataType = "datatype3";
editable = 1;
maxValue = 300;
minValue = 20;
order = 3;
title = "title3";
type = numeric;
units = kg;
}
);
name = "Name";
order = 1
title = "Title";
}
I want to get all keys within this dictionary.
I tried [myDict allKeys], however this is returning only four keys: DataTypes, name, order, title.
I want to retrieve all keys: dataType, editable, maxvalue, etc.
Try this.
NSArray *tempArray = [myDict objectForKey:#"dataTypes"];
NSDictionary *tempDictionary = (NSDictionary *)tempArray[0];
[tempDictionary allKeys] will have what you want.
Write this method.
- (NSDictionary *)dictionaryFromArrayWithinDictionary:(NSDictionary *)dictionary withKey:(NSString *)key{
NSArray *tempArray = [dictionary objectForKey:key];
return (NSDictionary *)tempArray[0];
}
This will return the inner dictionary and simply calling `allKeys' on this dictionary, you will get all the keys you want.
You need to recursively walk through your dictionary, and through any arrays the dictionary might contain, and so on. This can be nicely done via a recursiveKeys method added to all objects, which returns an empty array for objects that are not containers, and walks though the container for objects that are containers:
#interface NSObject(MyCategory)
- (NSArray)recursiveKeys;
#end
#implementation NSObject(MyCategory)
- (NSArray)recursiveKeys {
return #[];
}
#end
#implementation NSArrray(MyCategory)
- (NSArray)recursiveKeys {
NSMutableArray *result = [NSMutableArray array];
for (id item in self) {
[result addObjectsFromArray:[item recursiveKeys]];
}
return [result copy]; //return an immutable array
}
#end
#implementation NSSet(MyCategory)
- (NSArray)recursiveKeys {
NSMutableArray *result = [NSMutableArray array];
for (id item in self) {
[result addObjectsFromArray:[item recursiveKeys]];
}
return [result copy]; //return an immutable array
}
#end
#implementation NSDictionary(MyCategory)
- (NSArray)recursiveKeys {
NSMutableArray *result = [self.allKeys mutableCopy];
for (id key in self) {
[result addObjectsFromArray:[self[key] recursiveKeys];
}
return [result copy]; //return an immutable array
}
#end
You can use it like this:
NSArray *keys = myDictionary.recursiveKeys;
Please pardon any syntax errors, I don't have at this time an Xcode in front of me, I simply typed the code here on SO.
I have a large array (which I want to graph), and I want to reduce the size of it by removing every other element in it. If I have an array like:
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"Hello", #"Again", #"World", #"I", #"Test", #"All-Day", nil];
How would I be able to get it down to:
(Hello, World, Test)
Any solution involving removeObjectAtIndex: is O(N^2), which you might not want since you said you “have a large array”.
#interface NSMutableArray (FG8_removeOddElements)
- (void)removeOddElements;
#end
#implementation NSMutableArray (FG8_removeOddElements)
- (void)removeOddElements {
// Given (a, b, c), result is (a, c), so round up.
NSUInteger finalCount = (self.count + 1) / 2;
// Element 0 never moves so start at 1.
for (NSUInteger i = 1; i < finalCount; ++i) {
self[i] = self[i * 2];
}
[self removeObjectsInRange:NSMakeRange(finalCount, self.count - finalCount)];
}
#end
Assuming removeObjectsInRange: is efficient, this performs the work in O(N) time.
UPDATE
Since HotLicks seems to think this algorithm doesn't work, here's a test:
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSMutableArray *array = #[#"a", #"b", #"c", #"d", #"e", #"f", #"g"].mutableCopy;
[array removeOddElements];
NSLog(#"%#", array);
}
#end
And here's the output:
2014-05-08 15:23:44.123 tester[43347:303] (
a,
c,
e,
g
)
Use a function like this:
- (NSMutableArray *)removeEveryOtherElement:(NSMutableArray *)array
{
NSLog(#"Input array: %#", array);
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
for (int x = 0; x<=array.count - 1; x++) {
if (x % 2 == 0) { // if the index of the object is "even" (divisible by 2)
[returnArray addObject:[array objectAtIndex:x]];
}
}
NSLog(#"Returned array: %#", returnArray);
return returnArray;
}
You have to watch out, because if you're performing operations on an NSMutableArray the indices will change as you're adding and removing objects (thus the problem with my first answer).
Output:
2014-05-08 16:14:14.693 test[2013:303] Input array: (
0,
1,
2,
3,
4,
5
)
2014-05-08 16:14:14.693 test[2013:303] Returned array: (
0,
2,
4
)
I am new to Objective C and I'm having trouble getting my head around a few things.
I am trying to make a big integer program, from which I read items entered in a string and put them into an individual elements in the array.
I am currently working on an add method which adds elements from both the arrays together to make a big number stored in a final array.
But I'm kind of confused about to get this array I made from the initWithString method into the array method. I have some understanding of self, but I don't really know how to use it in this sense.
#implementation MPInteger
{
}
-(id) initWithString: (NSString *) x
{
self = [super init];
if (self) {
NSMutableArray *intString = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[intString addObject:ch];
}
}
return self;
}
-(NSString *) description
{
return self.description;
}
-(MPInteger *) add: (MPInteger *) x
{
//NSMutableArray *arr1 = [NSMutableArray arrayWithCapacity:100];
//NSMutableArray *arr2 = [NSMutableArray arrayWithCapacity:100];
//for (int i=0; i < 100; i++) {
//int r = arc4random_uniform(1000);
//NSNumber *n = [NSNumber numberWithInteger:r];
//[arr1 addObject:n];
//[arr2 addObject:n];
// }
self.array = [NSMutableArray initialize];
return x;
}
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
MPInteger *x = [[MPInteger alloc] initWithString:#"123456789"];
MPInteger *y = [[MPInteger alloc] initWithString:#"123456789"];
[x add: y];
}
}
So I want too add the x and y arrays, but I'm not sure how to get the arrays in the add method. Do I use self to represent one of the arrays and initialise it, and x to represent the other. I don't know if I'm going about it completely the wrong way. Some help to understand would be greatly appreciated.
When referring to self you're actually accessing the current instance of the class. In other languages this may be implemented as this instead. There are a couple ways of designing the approach you're going for but the simplest pattern is probably composition:
#interface MPInteger
{
NSMutableArray *digits;
}
#end
----------------------------------------------------------------------------
#implementation MPInteger
-(id) initWithString: (NSString *) x
{
// Create a new instance of this class (MPInteger) with a default
// constructor and assign it to the current instance (self).
self = [super init];
if (self) {
// Previously we initialized a string, but then threw it out!
// Instead, let's save it to our string representation:
self->digits = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[self->digits addObject:ch];
}
return self;
}
// Depending on how you want to implement this function, it could return
// a new MPInteger class or update the current instance (self):
-(MPInteger *) add: (MPInteger *) x
{
NSArray *a = self->digits;
NSArray *b = x->digits;
// Have both strings for A + B, so use them to find C:
NSArray *c = ????;
// Return a new instance of MPInteger with the result:
return [ [ MPInteger alloc ] initWithString:c ];
}
#end
Notice that now the MPInteger class has an instance of an NSString object that will exist during the entire lifetime of the MPInteger object. To update/access this string, all you need to do is say:
self->digits
I have an NSArray, and I've calculated a list of integers that represent (in binary) the elements I need to pull out of the array into a new array.
For example, I have 7, 11, and 13, whose bit patterns are 000111, 001011, and 001101. I want to grab three arrays, made of elements 0,1,2, then elements 0,1,3, and then 0,2,3 out of the main array.
Construct an NSIndexSet from the bit patterns you have:
#implementation NSIndexSet (NonContiguous)
+ (instancetype)indexSetFromMask:(NSUInteger)mask
{
NSMutableIndexSet * set = [NSMutableIndexSet indexSet];
for( NSUInteger i = 0; i < (sizeof(NSUInteger) * 8); i++ ){
if( mask & (1l << i) ){
[set addIndex:i];
}
}
return set;
}
#end
Then use objectsAtIndexes:
[origArray objectsAtIndexes:[NSIndexSet indexSetFromMask:7]];
// etc.
Assuming you want the output to be in the form [[a,b,c],[a,b,d],[a,c,d]] for the example, you could do something like this:
NSArray *sourceArray = [[NSArray alloc] initWithObjects:#"a",#"b",#"c",#"d",...,nil];
NSArray *grabArray = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:7],[NSNumber numberWithInt:11],[NSNumber numberWithInt:13],...,nil];
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
Then for each element of grabArray, add the correct elements to resultArray:
for (NSNumber num in grabArray) {
int n = [num intValue];
int bit = floor(log2(n)); //get highest bit in the current number
NSMutableArray *curr = [[NSMutableArray alloc] init];
while (n>0) {
if (n>pow(bit,2)) { //if this bit is a 1
[curr addObject:[sourceArray objectAtIndex:bit]];
}
n-=pow(bit,2);
bit-=1;
}
[resultArray addObject:curr];
}
Then resultArray should be the array you are looking for. It will add the objects in reverse order, so if order matters you would want to use [curr insertObject: [sourceArray objectAtIndex:bit] atIndex:0]; instead.
Whats the easiest way to declare a two dimensional array in Objective-C? I am reading an matrix of numbers from a text file from a website and want to take the data and place it into a 3x3 matrix.
Once I read the URL into a string, I create an NSArray and use the componentsSeparatedByString method to strip of the carriage return line feed and create each individual row. I then get the count of the number of lines in the new array to get the individual values at each row. This will give mw an array with a string of characters, not a row of three individual values. I just need to be able to take these values and create a two dimensional array.
If it doesn't need to be an object you can use:
float matrix[3][3];
to define a 3x3 array of floats.
You can use the Objective C style array.
NSMutableArray *dataArray = [[NSMutableArray alloc] initWithCapacity: 3];
[dataArray insertObject:[NSMutableArray arrayWithObjects:#"0",#"0",#"0",nil] atIndex:0];
[dataArray insertObject:[NSMutableArray arrayWithObjects:#"0",#"0",#"0",nil] atIndex:1];
[dataArray insertObject:[NSMutableArray arrayWithObjects:#"0",#"0",#"0",nil] atIndex:2];
I hope you get your answer from the above example.
Cheers,
Raxit
This will also work:
NSArray *myArray = #[
#[ #1, #2, #3, #4],
#[ #1, #2, #3, #4],
#[ #1, #2, #3, #4],
#[ #1, #2, #3, #4],
];
In this case it is a 4x4 array with just numbers in it.
I'm not absolutely certain what you are looking for, but my approach to a two dimensional array would be to create a new class to encapsulate it. NB the below was typed directly into the StackOverflow answer box so it is not compiled or tested.
#interface TwoDArray : NSObject
{
#private
NSArray* backingStore;
size_t numRows;
size_t numCols;
}
// values is a linear array in row major order
-(id) initWithRows: (size_t) rows cols: (size_t) cols values: (NSArray*) values;
-(id) objectAtRow: (size_t) row col: (size_t) col;
#end
#implementation TwoDArray
-(id) initWithRows: (size_t) rows cols: (size_t) cols values: (NSArray*) values
{
self = [super init];
if (self != nil)
{
if (rows * cols != [values length])
{
// the values are not the right size for the array
[self release];
return nil;
}
numRows = rows;
numCols = cols;
backingStore = [values copy];
}
return self;
}
-(void) dealloc
{
[backingStore release];
[super dealloc];
}
-(id) objectAtRow: (size_t) row col: (size_t) col
{
if (col >= numCols)
{
// raise same exception as index out of bounds on NSArray.
// Don't need to check the row because if it's too big the
// retrieval from the backing store will throw an exception.
}
size_t index = row * numCols + col;
return [backingStore objectAtIndex: index];
}
#end
First you to have set An NSMutableDictionary on .h file
#interface MSRCommonLogic : NSObject
{
NSMutableDictionary *twoDimensionArray;
}
then have to use following functions in .m file
- (void)setValuesToArray :(int)rows cols:(int) col value:(id)value
{
if(!twoDimensionArray)
{
twoDimensionArray =[[NSMutableDictionary alloc]init];
}
NSString *strKey=[NSString stringWithFormat:#"%dVs%d",rows,col];
[twoDimensionArray setObject:value forKey:strKey];
}
- (id)getValueFromArray :(int)rows cols:(int) col
{
NSString *strKey=[NSString stringWithFormat:#"%dVs%d",rows,col];
return [twoDimensionArray valueForKey:strKey];
}
- (void)printTwoDArray:(int)rows cols:(int) cols
{
NSString *strAllsValuesToprint=#"";
strAllsValuesToprint=[strAllsValuesToprint stringByAppendingString:#"\n"];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
NSString *strV=[self getValueFromArray:row cols:col];
strAllsValuesToprint=[strAllsValuesToprint stringByAppendingString:[NSString stringWithFormat:#"%#",strV]];
strAllsValuesToprint=[strAllsValuesToprint stringByAppendingString:#"\t"];
}
strAllsValuesToprint= [strAllsValuesToprint stringByAppendingString:#"\n"];
}
NSLog(#"%#",strAllsValuesToprint);
}
Hope this helps.
This is just example how you can initial 2d array of int in code (Objective C works)
int **p;
p = (int **) malloc(Nrow*sizeof(int*));
for(int i =0;i<Nrow;i++)
{
p[i] = (int*)malloc(Ncol*sizeof(int));
}
//put something in
for(int i =0;i<Nrow;i++)
{
p[i][i] = i*i;
NSLog(#" Number:%d value:%d",i, p[i][i]);
}
//free pointer after use
for(int i=0;i<Nrow;i++)
{
p[i]=nil;
//free(p[i]);
NSLog(#" Number:%d",i);
}
//free(**p);
p = nil;