Invalid operands to binary expression ('NSMutableArray' and 'double') - ios

I want to store double value into Array and later combine to compute some results but I have encounter some error. Is there another way to do it?
NSMutableArray *storeImpedance;
NSMutableArray *storeLength;
double designFrequency = 1e9;
double simulateFrequency = 1.5e9;
double pi = 3.14159265359;
double omega = 2*pi*simulateFrequency;
double Z0=50;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
storeImpedance = [[NSMutableArray alloc]initWithCapacity:25];
storeLength = [[NSMutableArray alloc]initWithCapacity:25];
}
- (IBAction)addButton:(UIButton *)sender {
storeCount++;
[storeImpedance addObject:[NSNumber numberWithDouble:[impedanceTextField.text doubleValue]]];
[storeLength addObject:[NSNumber numberWithDouble:[lengthTextField.text doubleValue]]];
}
if (imageIndex==1)
{
thetarad=storeImpedance*pi/180*simulateFrequency/designFrequency;
A=cos(thetarad);
B=I* storeImpedance*sin(thetarad);
C=I*sin(thetarad)/storeImpedance;
D=cos(thetarad);
}

At this line:
hetarad=storeImpedance*pi/180*simulateFrequency/designFrequency;
You are using storeImpedance which is of type NSMutableArray and the expected type in this expressions is double.
Extract the required double value from the array and use it to fix the problem:
NSNumber *number = (NSNumber *)[storeImpedance firstObject]; // Or use objectAtIndex: for a specific value in the array if it is not the first one
double value = [number doubleValue];
hetarad=value*pi/180*simulateFrequency/designFrequency;
If you want to calculate hetarad for each value in the array:
for (id element in storeImpedance) {
NSNumber *number = (NSNumber *)element
double value = [number doubleValue];
hetarad=value*pi/180*simulateFrequency/designFrequency;
// You should do something with hetarad here (either store it or use in other required logic otherwise it will be overwritten by the next iteration
}

Related

I need to have a mutable Array that has 8 interpolated strings in IOS

I'm new to IOS and I'm not sure if I'm on the right track. What I need to know is if I'm on the right track and if I'm off it a hint on what to fix so I can get back on track. The mutable Array should read an array of speakers and say "Hello, my name is <speakerArray>" it should do that 8 times with a different name each time. This is what I Have:
- (NSArray*)badgesForSpeakers:(NSArray*)speakers {
for(speakers i = 0; i => 7; i++)
{
NSString *greetings =#"Hello, my name is .";
NSMutableArray *badges = [speakers arrayByAddingObjectsFromArray:greetings];
}
return badges;
}
Let's take this one step at a time. First of all, your operator in the loop is wrong; you mean to execute while i is less than or equal to 7. Thus, change => to <=. However, it's more stylish to say i < 8. And finally, it's most stylish of all to use what's called "Fast Enumeration", which allows you to loop without an index at all. In fact, it will work no matter how many items are in your speakers array! That takes us here:
- (NSArray*)badgesForSpeakers:(NSArray*)speakers {
for (NSString* speaker in speakers)
{
NSString *greetings =#"Hello, my name is .";
NSMutableArray *badges = [speakers arrayByAddingObjectsFromArray:greetings];
}
return badges;
}
Next, greetings isn't an array! It's a string. That's why calling -arrayByAddingObjectsFromArray: doesn't make any sense, and why the compiler isn't going to like it. Let's make its name singular, greeting, to reflect this fact. Strategy: Your goal here is to create an empty array, then construct items one by one and add them to that array. That takes us to:
- (NSArray*)badgesForSpeakers:(NSArray*)speakers {
NSMutableArray *badges = [NSMutableArray array]; //Here we make an empty array
for (NSString* speaker in speakers)
{
NSString *greeting =#"Hello, my name is .";
[badges addObject:greeting]; //Here we add one item to it each time 'round the loop
}
return badges;
}
Last, your string has no interpolation right now! It reads literally "Hello, my name is ." We do string interpolation using the -stringWithFormat: method.
Finished Product:
- (NSArray*)badgesForSpeakers:(NSArray*)speakers {
NSMutableArray *badges = [NSMutableArray array];
for (NSString* speaker in speakers)
{
NSString *greeting = [NSString stringWithFormat:#"Hello, my name is %#.",speaker];
[badges addObject:greeting];
}
return badges;
}
That should get you started with fast enumeration and string interpolation. Remember to compile your code often and try to understand the compiler errors--it would have helped you with some of these issues.
Maybe you mean this
- (NSMutableArray *)badgesForSpeakers:(NSArray *)speakers {
NSMutableArray *badges = [[NSMutableArray alloc] init];
for (NSString *speaker in speakers) {
[badges addObject:[NSString stringWithFormat:#"Hello, my name is %#", speaker]];
}
return badges;
}
plz use this code
- (NSArray*)badgesForSpeakers:(NSArray*)speakers {
NSMutableArray *badges = [NSMutableArray alloc];
for(int i = 0; i < speakers.count; i++)
{
NSString *greetings =[NSString stringWithFormat:#"Hello, my name is .%#",[speakers objectAtIndex:i]];
badges = [speakers addObject:greetings];
}
return [badges copy];
}

Return the first number which occurs only once in an NSArray

I would like to know what's the best or most appropriate approach for this question: Given a list of numbers example [2, 3, 4, 2, 3], return the first number that occurs only once in the list.
I have followed some algorithms approach and came up with this, but not sure if there are any built-in helper functions in Objective-C that will allow me to do this with a better performance..
If there are not built-ins solutions, is there is any improvements that can be made to my approach or any other solution that could be better in terms of performance?
This is my updated solution for this:
For testing:
#import "NSArray+Addons.h"
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray<NSNumber *> *array = #[#(2), #(7), #(3), #(2), #(3), #(2), #(7), #(3), #(2), #(3), #(4), #(7), #(5), #(5), #(9)];
NSLog(#"Unique number: %#", [array firstUniqueNumber]);
}
#end
NSArray category:
#import "NSArray+Addons.h"
#import "NSMutableDictionary+Addons.h"
#implementation NSArray (Addons)
- (NSNumber *)firstUniqueNumber
{
if (!self.count)
{
return nil;
}
NSMutableDictionary<NSNumber *, NSNumber *> *myUniqueNumbers = [[NSMutableDictionary alloc] init];
return [myUniqueNumbers uniqueValueFromArray:self];
}
#end
NSMutableDictionary category:
#import "NSMutableDictionary+Addons.h"
#implementation NSMutableDictionary (Addons)
- (NSNumber *)uniqueValueFromArray:(NSArray<NSNumber *> *)array
{
if (!array.count)
{
return nil;
}
for (NSNumber *number in array)
{
if (!self[number])
{
self[number] = [NSNumber numberWithInteger:1];
}
else
{
NSInteger count = [self[number] integerValue];
count++;
self[number] = [NSNumber numberWithInteger:count];
}
}
return [self uniqueNumberWithArray:array];
}
- (NSNumber *)uniqueNumberWithArray:(NSArray<NSNumber *> *)array
{
if (!array.count)
{
return nil;
}
NSNumber *uniqueNumber = nil;
for (NSInteger index = array.count - 1; index > 0; index--)
{
NSNumber *key = array[index];
if (self[key] && [self[key] integerValue] == 1)
{
uniqueNumber = key;
}
}
return uniqueNumber;
}
#end
NSCountedSet* set = [[NSCountedSet alloc] initWithArray:array];
NSUInteger index = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){
return [set countForObject:obj] == 1;
}];
return index == NSNotFound ? nil : [array objectAtIndex:index];
This problem can be reduced to element distinctness problem, so there is no linear time solution, without using hashing and extra space.
One simple solution in O(n) time on average + space is:
Build a hash based histogram of the data, that maps each value to the number of its occurances.
Find the first number in the array that its value in the histogram is 1.
Pseudo code:
map = new hashmap
for each element x:
if map contains x is a key:
map.put(x,map.get(x)+1)
else:
map.put(x,1)
for each element x in array:
if map.get(x) == 1:
return x
//if reached here - no distinct element
Example:
array = [2, 3, 4, 2, 3]
create histogram: {[2=2] [3=2], [4=1]}
iterate the array:
check 2, it has value of 2 in histogram. continue
check 3, it has value of 2 in histogram. continue
check 4, it has value of 1 in histogram. Return it and finish.
-(NSNumber *)returnFirstUniqueFromArray: (NSArray *)array{
//put the numbers in a set
NSCountedSet *numbers = [[NSCountedSet alloc] initWithArray:array];
for(NSNumber *number in array){
//if it only occurs once return
if([numbers countForObject:number]==1) return number;
}
return nil;
}
They key being here you need a good way to keep track of how many times something occurs so take advantage of NSCountedSet's "count" method. Will tell you how many times an object occurs.

How to find the average of a group of NSNumbers from NSMutableArray?

I have an NSMutableArray of NSNumbers that I have created using this code.
if (countMArray == nil) {
countMArray = [[NSMutableArray alloc] init];
}
if ([countMArray count] == 10) {
[countMArray removeObjectAtIndex:0];
}
NSNumber *currentX = [NSNumber numberWithDouble:x];
[countMArray addObject:currentX];
NSLog(#"%#", countMArray);
this is how my array looks.
2014-05-02 20:34:35.065 MotionGraphs[3721:60b] (
"0.0292816162109375",
"0.0315704345703125",
"0.03271484375",
"0.030517578125",
"0.03094482421875",
"0.0302886962890625",
"0.03192138671875",
"0.0306396484375",
"0.03094482421875",
"0.02874755859375"
)
I would like to find the average of the 10 numbers, I understand the mathematics behind it are simple: add all the values then divide by 10. However, I would like to know the best way to attempt this.
If you simply wanted to average all the countMArray in the numbers array, you could use KVC collection operator:
NSNumber *average = [countMArray valueForKeyPath:#"#avg.self"];
You should use if array contains NSNumber
NSNumber *average = [countMArray valueForKeyPath:#"#avg.doubleValue"];
But you are having NSStrings, so use this below method
-(double)avgOfArray:(NSArray*)array{
double total=0.0;
for (NSString *aString in array) {
total+=[aString doubleValue];
}
return ([array count]>0)?(total/[array count]):total;
}

How to randomize letters correctly from an NSString

I am creating a word scrambler and I am having issues randomizing the letters. When the letters get randomized, it doesn't make sense.
For example, the word PARK shows as AAPA. So, as you can tell it won't make sense for the user when it is time to unscramble.
Just so you know, I am using a .plist file to hold the words.
This is the code I am using to randomize the letters:
_words = [NSMutableArray arrayWithCapacity:scramblelength];
for (int i=0;i<scramblelength;i++) {
NSString *letter = [scramble substringWithRange:[scramble rangeOfComposedCharacterSequenceAtIndex:arc4random()%[scramble length]]];
Then, I am creating UIImageViews to display the scrambled words:
if (![letter isEqualToString:#""]) {
GameView *boxes = [[GameView alloc] initWithLetter:letter andSideLength:boxSide];
boxes.center = CGPointMake(xOffset + i*(boxSide + kTileMargin), kScreenHeight/4*3);
[self.scrambleView addSubview:boxes];
[_words addObject:boxes];
What am I doing wrong here? I would like for the letters in the scrambled words to make sense.
Please help, I am stuck on this one!
Thanks!
As long as your string length will fit in 32 bits, this should be fine. If not, I would replace arc4random_uniform with a uniform random number generator in C++ and compile this as an Objective-C++ module.
The code simply iterates through the string, and swaps each composed character sequence with some random composed character sequence from the same string.
Sorry, that's what happens when you are arrogant and just type out code. Let me know if you have trouble with this one...
For much larger strings, there is a more efficient way, but this seems to do the trick.
NSMutableString category...
#interface NSMutableString (Scramble)
- (void)scramble;
#end
#implementation NSMutableString (Scramble)
static void
swapRanges(NSMutableString *string, NSRange iRange, NSRange jRange)
{
// Need to replace the "trailing" component first
if (NSEqualRanges(iRange, jRange)) return;
if (iRange.location > jRange.location) {
NSRange tmpRange = iRange;
iRange = jRange;
jRange = tmpRange;
}
NSString *iString = [self substringWithRange:iRange];
NSString *jString = [self substringWithRange:jRange];
[string replaceCharactersInRange:jRange withString:iString];
[string replaceCharactersInRange:iRange withString:jString];
}
- (void)scramble
{
for (NSUInteger i = 0; i < self.length; ++i) {
NSRange iRange = [self rangeOfComposedCharacterSequenceAtIndex:i];
NSUInteger j = arc4random_uniform(self.length);
NSRange jRange = [self rangeOfComposedCharacterSequenceAtIndex:j];
swapRanges(self, iRange, jRange);
}
}
#end
NSString category...
#interface NSString (Scramble)
- (NSString*)scrambledString;
#end
#implementation NSString (Scramble)
- (NSString *)scrambledString
{
NSMutableString *result = [self mutableCopy];
[result scramble];
return [result copy];
}
#end
Sample use...
[someMutableString scramble];
NSString *mixedUp = [someString scrambledString];
Or, if you are comfortable with C++, convert to a std::wstring, call std::random_shuffle, then convert that to a NSString. Lots less bugs when using proven, well tested code.
When you are getting a random letter, you need to do something to remove that letter from your NSMutableArray (ie the word's letters when in order). So as you iterate through the word, each time there are fewer characters remaining. Right now, from your limited code block (the first one), it appears you might not be doing that. You want something like "[_words removeObjectAtIndex:letterIndex]" and you would also want to iterate from number of letters down to zero as you remove items from the array also: for (int i=[_words count]; i > [_words count]; i--) because you need to go from 4 letters down to 0 letters left.
So, I'm sure there are more efficient ways to do this, but I go by the rule of not optimizing until you need to. With that in mind, this code appears to work correctly:
- (NSString *)scrambleWord:(NSString *)word {
NSMutableArray *letterArray = [self letterArrayFromWord:word];
NSMutableString *returnValue = [[NSMutableString alloc] init];
do {
int randomIndex = arc4random() % letterArray.count;
[returnValue appendString:letterArray[randomIndex]];
[letterArray removeObjectAtIndex:randomIndex];
if (letterArray.count == 1) {
[returnValue appendString:letterArray[0]];
break;
}
} while (YES);
if ([[returnValue copy] isEqualToString:word]) {
return [self scrambleWord:word];
} else {
return [returnValue copy];
}
}
- (NSMutableArray *)letterArrayFromWord:(NSString *)word {
NSMutableArray *array = [NSMutableArray array];
for (int i = 0; i < word.length; i = i + 1) {
[array addObject:[NSString stringWithFormat:#"%C", [word characterAtIndex:i]]];
}
return array;
}

Using Block sortedArrayUsingComparator:^(id a, id b)

In my project, I try to compare a known location to an inputted location by using block sortedArrayUsingComparator:^(id a, id b). I have a dictionary array called locationArray containing a lat long and a station number that corresponds to that lat long point. I try to compare each locationArray station to the inputted station. I do this by taking the absolute value of the difference between the two which gives me a distance. Then I try to sort locationArray based on the distance from the inputted station from closest to furthest away.
//locationArray
#define kStation #"station"
#define kLatitude #"latitude"
#define kLongitude #"longitude"
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"499CSV" ofType:#"csv"];
NSString *csvString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
NSArray *locations = [csvString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSMutableArray *CSVArray = [NSMutableArray array];
NSCharacterSet *whiteSPNewLine = [NSCharacterSet whitespaceAndNewlineCharacterSet];
for (NSString * location in locations)
{
NSArray *components = [location componentsSeparatedByString:#","];
double latitude = [[components[0] stringByTrimmingCharactersInSet:whiteSPNewLine] doubleValue];
double longitude = [[components[1] stringByTrimmingCharactersInSet:whiteSPNewLine] doubleValue];
NSString *station = [components[2] stringByTrimmingCharactersInSet:whiteSPNewLine];
NSDictionary *dict = #{kLatitude: #(latitude),
kLongitude: #(longitude),
kStation: station};
[CSVArray addObject:dict];
}
NSLog(#"The contents of CSVArray = %#",[CSVArray description]);
{
latitude = "41.674364";
longitude = "-81.23700700000001";
station = 40150;
},
{
latitude = "41.67517";
longitude = "-81.235038";
station = 40763;
},
{
latitude = "41.673106";
longitude = "-81.24017499999999";
station = 39175;
}, ...
My block code that directly follows locationArray.
NSArray *orderedPlaces = [CSVArray sortedArrayUsingComparator:^(id a, id b) {
NSDictionary *dictA;
NSDictionary *dictB;
NSString *locA;
NSString *locB;
int distanceA;
int distanceB;
dictA = (NSDictionary *)a;
dictB = (NSDictionary *)b;
NSLog(#"dictA = %#", dictA);
NSLog(#"dictB = %#", dictB);
locA = [dictA objectForKey:kStation];
locB = [dictB objectForKey:kStation];
NSLog(#"locA = %#", locA);
NSLog(#"locB = %#", locB);
distanceA = abs(stationNumber-[locA intValue]);
distanceB = abs(stationNumber-[locB intValue]);
NSLog(#"distanceA = %d", distanceA);
NSLog(#"distanceB = %d", distanceB);
if (distanceA < distanceB) {
return NSOrderedAscending;
} else if (distanceA > distanceB) {
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}];
NSLog(#"The contents of array = %#",[orderedPlaces description]);
The block runs but it's not sorting locationsArray as intended. orderedPlaces returns an unsorted locationsArray. By running NSLOG on the block components, I see that it successfully recognizes locationsArray and creates the distance object. I must be missing something because I use the same code in a different part of my project where I compare locationsArray to the lat long of the user's location and it works well. Please help me identify the issue keeping it from working as intended.
*If you need any more information or clarification, just ask.
I don't understand your sort block. You're calculating distance A as abs(stationNumber-[locA intValue]).
What is stationNumber? Is that some fixed integer index? How can the difference between a fixed station number and the station numbers in your array have anything to do with distances?
It seems to me that your distance values should be
(target.lat - this_station.lat)^2 + (target.long - this_station.long)^2
That will give you the square of the pythagorean distance between your target point and one of the stations you are comparing. Then in your comparison you select the item who's distance squared is less.
You can skip the square root, because you're just comparing them. That will make your distance calculations much faster.
Try this:
NSArray *orderedPlaces = [CSVArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
^(id a, id b) means ^void (id a, id b) and your return value is ignored.

Resources