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
Related
I am new to objective c and having some problem with nsmutableArray.I have button and two textfields on my gui and i want that when i click on button the strings from textfields should be added to my existing array. But the problem is that when i click on button it always create new array.Help anybody.
my button code in myfile.m is as follows:
NSMutableArray* myArray = [NSMutableArray array];
NSString *strr=[textf stringValue];
NSString *strr1=[textf1 stringValue];
// [myArray addObject:strr]; // same with float values
// [myArray addObject:strr1];
[myArray addObject:strr];
[myArray addObject:strr1];
int i,j=0;
int count;
for (i = 0, count = [myArray count]; i < count; ){
NSString *element = [myArray objectAtIndex:i];
NSLog(#"The element at index %d in the array is: %#", i, element);
}
Because you always create new array in this line:
NSMutableArray* myArray = [NSMutableArray array];
Make your array as property of your class object. Example:
#interface MyClass ()
#property (nonatomic, strong) NSMutableArray * array;
#end
#implementation MyClass
- (id)init {
self = [super init];
if ( self ) {
_array = [NSMutableArray array];
}
return self;
}
- (IBAction)onButtonClick {
NSString *strr = [textf stringValue];
NSString *strr1 = [textf1 stringValue];
[self.array addObject:strr];
[self.array addObject:strr1];
for ( int i = 0; i < [myArray count]; i++ ) {
NSString * element = [myArray objectAtIndex:i];
NSLog(#"The element at index %d in the array is: %#", i, element);
}
}
#end
I stored some strings in objects and added the objects to an NSMutableArray. Now I want to print the strings in each element of the array. Clearly, I'm doing something wrong. I'm going to back and review these basics, but I was hoping someone could explain how I can print the string instead of the what looks to be the element address.
/** interface **/
#property (nonatomic, copy) NSString*myNumber;
-(void)setNumber: (NSString*) randomNumber;
/** implementation **/
#synthesize myNumber;
-(void) setNumber:(NSString *)randomNumber
{
myNumber = randomNumber;
}
/**main**/
Fraction * aFrac = [[Fraction alloc] init];
[aFrac setNumber:#"5/6"];
Fraction * bFrac = [[Fraction alloc] init];
[bFrac setNumber:#"2/3"];
NSMutableArray * myArray = [[NSMutableArray alloc] init];
[myArray addObject:aFrac];
[myArray addObject:bFrac];
int i;
for(i = 0; i<2; ++i)
{
id myArrayElement = [myArray objectAtIndex:i];
NSLog(#"%#", myArrayElement);
}
for(i = 0; i<2; ++i)
{
NSLog(#"%#", myArray[i]);
}
Both for loops print the same thing.
When you pass a custom object to NSLog you have to override the -(NSString)description method in that object.
So in your Fraction class if you simply override this function like so
- (NSString*)description
{
return self.myNumber;
}
that should log out what you want.
I would probably think about renaming that property from number as you are storing a string.
Hope that helps
I'm guessing the Fraction type you created has a NSString property or method named number (to match the -setNumber: method), in which case you would use the following code to print it:
NSLog("%#", [myArrayElement number]);
Or, for the second loop:
NSLog("%#", [myArray[i] number]);
In your code both for loop meaning has same only, try below
for(i = 0; i<2; ++i)
{
id myArrayElement = [myArray objectAtIndex:i];
NSLog(#"%#", myArrayElement.number);
}
for(i = 0; i<2; ++i)
{
NSLog(#"%#", myArray[i].number);
}
Now here two array value you are extracting
[myArray objectAtIndex:i] which is equivalent to myArray[i]
I need a method that would add a few objects (2-10) to my array, skipping these that are nils:
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObjectsSkipNils:obj1, obj2, obj3];
How I can write this method in an elegant way?
This category method would work:
#interface NSMutableArray (MyAdditions)
- (void)addObjectsSkipNilsWithCount:(NSUInteger)count objects:(id)obj, ...;
#end
#implementation NSMutableArray (MyAdditions)
- (void)addObjectsSkipNilsWithCount:(NSUInteger)count objects:(id)obj, ...
{
va_list ap;
va_start(ap, obj);
// First object:
if (obj != nil)
[self addObject:obj];
// Remaining objects:
for (NSUInteger i = 1; i < count; i++) {
id myobj = va_arg(ap, id);
if (myobj != nil)
[self addObject:myobj];
}
va_end(ap);
}
#end
Example:
NSMutableArray *a = [NSMutableArray array];
[a addObjectsSkipNilsWithCount:3 objects:#"foo", nil, #"bar"];
NSLog(#"%#", a);
// Output: ( foo, bar )
You have to specify the number of objects explicitly, because nil cannot be used as terminator for the variable argument list. (And bad things can happen if the count is greater than the actual number of objects supplied !)
You can use:
[yourMainArray removeObjectIdenticalTo:[NSNull null]];
Now if you want to copy this to arr you can do quite easily.
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSMutableString *outputStringSet = [[NSMutableString alloc] init];
NSMutableString *outputStringArray = [[NSMutableString alloc] init];
NSMutableSet *mySet = [[NSMutableSet alloc] init];
NSMutableArray *myArray = [[NSMutableArray alloc] initWithCapacity: 10];
int userInput;
NSLog(#"Enter 10 numbers");
for( int i = 0; i < 10; i++) {
scanf("%i", &userInput);
NSNumber *input = [[NSNumber alloc] initWithInt: userInput];
[myArray addObject:input];
if([mySet member: input]) {
[mySet addObject: input];
}
}
for (int k = 0; k < [myArray count]; k++) {
[outputStringArray appendFormat:#"%#, ", [myArray objectAtIndex:k]];
}
NSLog(#"%#", [outputStringArray substringToIndex:[outputStringArray length] - 2]);
for (int j = 0; j < [myArray count]; j++) {
if([mySet containsObject: [myArray objectAtIndex:j]]) {
[outputStringSet appendFormat:#"%#, ", [myArray objectAtIndex:j]];
}
NSLog(#"%#", outputStringSet);
}
}
return 0;
}
Code above prints the array but not the appropriate object in the set
Why?
Please explain clearly. I am a bit of a noob, and couldnt find the answer anywhere else.
thanks
if([mySet member: input]) {
[mySet addObject: input];
}
You're adding the object to the set if it’s already in it. You want the reverse: add the object if it's not in it.
Thus:
if ( ! [mySet member:input] )
[mySet addObject:input];
By the way, you should use containsObject: instead of member: in your test:
containsObject:
Returns a Boolean value that indicates whether a given
object is present in the set.
- (BOOL)containsObject:(id)anObject
Edit: you don't even need to test if the object is already in the set before adding it. After all, that's the main purpose of a NSSet: to ensure uniqueness of its objects. So if you add an object twice, the second call will silently be ignored, as the object is alreay in it.
Your set is empty because of
if([mySet member: input]) {
[mySet addObject: input];
}
member:
Determines whether the set contains an object equal to a given object,
and returns that object if it is present.
I can create an NSArray that contains all the hash values of the objects in myArray like this:
NSArray *a = [myArray valueForKey:#"hash"];
What key do I pass to valueForKey: to get an array containing myArray's indices?
Say myArray has n items. I'd like to do something like this:
NSArray *a = [myArray valueForKey:#"index"];
NSArray * arrayWithNumbersInRange( NSRange range )
{
NSMutableArray * arr = [NSMutableArray array];
NSUInteger i;
for( i = range.location; i <= range.location + range.length; i++ ){
[arr addObject:[NSNumber numberWithUnsignedInteger:i];
}
return arr;
}
NSArray * indexArray = arrayWithNumbersInRange((NSRange){0, [myArray length]-1});
You can query an NSArray for the index of an object with indexOfObject:
NSArray *a = [myArray valueForKey:#"hash"];
NSInteger index = [myArray indexOfObject:a];
Create a superclass of NSArray which returns the index:
//
// CapArrayOfIndex.h
// Created by carmin politano on 7/26/12.
// no rights reserved
//
#interface CapArrayOfIndex : NSArray {
/*! Simulated constant array containing an array of NSNumber representing the index. */
NSUInteger iCount;
//*! NSNotFound causes bybass of index bounds testing. */
}
#pragma mark create
+ (CapArrayOfIndex*) withCount: (NSUInteger) aCount;
#end
and
//
// CapArrayOfIndex.mm
// Created by carmin on 7/26/12.
// no rights reserved
//
#import "CapArrayOfIndex.h"
#implementation CapArrayOfIndex
#pragma mark NSCopying
- (id) copyWithZone: (NSZone*) aZone {
/*! New allocation required because -count is a mutable property. */
return [CapArrayOfIndex withCount: self.count];
}
#pragma mark create
+ (CapArrayOfIndex*) withCount: (NSUInteger) aCount {
CapArrayOfIndex* zArray = self.alloc;
zArray->iCount = aCount;
return zArray;
}
#pragma mark NSArray
- (NSUInteger) count {
return iCount;
}
- (void) setCount: (NSUInteger) aCount {
iCount = aCount;
}
- (id) objectAtIndex: (NSUInteger) aIndex {
/*! My code performs a bounds test using unusual macros: return [ViaUInteger RaiseIfObjectAtIndex(nil, self, aIndex, nil)]; */
return [NSNumber numberWithInteger: aIndex];
}
#end