Issue with UITextfield into a NSMutableArray - ios

I had this working using NSArray until I realize I need to insert a string into array. Now I'm changing this to a NSMutableArray, but having issues with my syntax. Am I allowed to use componentsJoinedByString in NSMutable arrays?
NSString *item;
int numofSeg;
int needSeg;
if (textfield.text == #"::") {
numofSeg = 0;
}
NSMutableArray *dlist = [[NSMutableArray alloc]init];
//take string from textfield and split it into a list on colons.
dlist = [textfield.text componentsSeparatedByString:#":"];
//run through list to count how many segments. Non blank ones.
for (item in dlist) {
if (item != #""){
numofSeg = numofSeg + 1;
NSLog(#"%#",numofSeg);
}
}
//determine number of segments
needSeg = 8 - numofSeg;
while (needSeg > 0) {
//insert 0000 at blank spot
[dlist insertString:#"0000" atIndex:#""];
needSeg = needSeg - 1;
}
for (item in dlist) {
if (item == #"") {
//remove blank spaces from list
[dlist removeAllObjects:item];
}
}
//join the list of times into a string with colon
NSString *joinstring = [dlist componentsJoinedByString:#":"];
NSLog(#"%#",joinstring);

I don't think NSMutableArray has a method called insertString:atIndex:. You should probably use insertObject:atIndex: instead.
What error do you get exactly?
Edit:
If you only use the NSMutableArray to insert #"0000" before #" ", then you can simply do:
string = [string stringByReplacingOccurrencesOfString:#" " withString:#" 0000"];
or something like that. No need to use NSMutableArray.

I finally figured it out. This is what I ended up using to fix this:
NSString *z = #"0000";
z = [z stringByAppendingString:#""];

Related

How to convert string into an IP Address?

I am using a function to adding . after every three characters inside the string. But how can i remove "0" in front of number.
-(NSString *)formatStringAsIpAddress:(NSString*)MacAddressWithoutColon
{
NSMutableString *macAddressWithColon = [NSMutableString new];
for (NSUInteger i = 0; i < [MacAddressWithoutColon length]; i++)
{
if (i > 0 && i % 3 == 0)
[macAddressWithColon appendString:#"."];
unichar c = [MacAddressWithoutColon characterAtIndex:i];
[macAddressWithColon appendString:[[NSString alloc] initWithCharacters:&c length:1]];
}
return macAddressWithColon;
}
If i have ip address 010.000.001.016
How can i set it up like 10.0.1.16? and if i have ip address 192.168.001.001? how to remove front 0's from IP address ?
What I would suggest:
NSString *ipAddress = #"010.000.001.016";
Split string into array of substrings:
NSArray *ipAddressComponents = [myString componentsSeparatedByString:#"."];
Run through the array with for loop and convert each to a int representation:
for(int i = 0; i < ipAddressComponents.count;i++)
{
[ipAddressComponents objectAtIndex:i] = [NSString stringWithFormat:#"%d",[[ipAddressComponents objectAtIndex:i]intValue]];
}
Join the array back into a string
NSString *newIpAddress = [ipAddressComponents componentsJoinedByString:#"."];
This should result into getting an IP address: 10.0.1.16
You can use string function and get your expected output with the help of componentsSeparatedByString and componentsJoinedByString functions.
Use below method for the same:
-(NSString*)removeZeroPrefix:(NSString*)aStrIP{
NSMutableArray *subStringArray = [[NSMutableArray alloc] init];
NSArray *arrayOfSubString = [aStrIP componentsSeparatedByString:#"."];
for (NSString *aSingleString in arrayOfSubString)
{
[subStringArray addObject:[NSNumber numberWithInteger:[aSingleString integerValue]]];
}
return [subStringArray componentsJoinedByString:#"."];
}
Usage :
[self removeZeroPrefix:#"010.000.001.016"];
[self removeZeroPrefix:#"192.168.001.001"];
Output :
Printing description of aStrIP:
10.0.1.16
Printing description of aStrIP:
192.168.1.1
hope this will helps!
In Swift
let ip = "0125.052.000.10"
let split = ip.components(separatedBy: ".")
for number in split {
if let isNumber = Int(number){
print(isNumber) // add this isNumber into array which is shows without initial zeros.
}
}
Finally join created array as String with dot Component

Check if string is already exist and add a number as suffix to the string in the array?

I have a name as "Ryan" and next time entering "Ryan" it should check it has the value,So it should make it "Ryan_1". The same way it should check if anytime someone added again "Ryan" it should change it to "Ryan_2".
Example:
nameArray = ["Ryan","John","Ryan_2","Rhonda","Ryan_3","Kylie","Ryan_4","John_2"];
I am using below code which is working fine while adding the name first time.
But when I am coming back to the section and editing value Ex: I changed Ryan_2 to "xyz" and again thought of keeping "Ryan" the saved value is becoming "Ryan_4" where as it supposed to be "Ryan_2" in the array. And let say if I am changing "Ryan_4" to "somenewName" now the numbering of other duplicate names also get rearranged.
NSMutableArray *array = [[NSMutableArray alloc]init];
int occurrences = 0;
for(NSString *string in nameArray) {
if ([value isKindOfClass:[NSString class]]) {
if ([string containsString:value]) {
[array addObject:string];
}
occurrences+= ([string containsString:value] ? 1 : 0);
}
}
if ([value isKindOfClass:[NSString class]]) {
if (![value isEqualToString:#""]) {
if (occurrences > 1) {
value = [value stringByAppendingFormat:#"_%d", occurrences];
}
}
}
I would recommend an extension like this:
extension NSMutableArray {
public func appendWithSuffix(strNewEntry:String) {
var n = 1
var new = strNewEntry
if self.containsObject(strNewEntry) {
new = strNewEntry + "_\(n)"
while self.containsObject( new ){
n += 1
new = strNewEntry + "_\(n)"
}
}
self.addObject( new )
}}
It will look for an exact match and insert if none is found, i.e it will add "Ryan_5" instead of "Ryan", "John_3" instead of "John" and so on.
Another approach may be to iterate thru all entries for comparison or filter the array with "namexy".hasPrefix("Ryan") to get max index of name to be inserted.
- (IBAction)SaveText:(id)sender
{
if (array.count==0)
{
[array addObject:_txtAddText.text];
}else
{
for(NSString *string in array)
{
if ([string containsString:_txtAddText.text] )
{
count = count+1;
NSString *Localstring =[NSString stringWithFormat:#"%#%d",[string stringByAppendingString:#"_"],count];
NSLog(#"%#",Localstring);
[array addObject:Localstring];
break;
}else
{
[array addObject:_txtAddText.text];
}
}
}
NSLog(#"%#",array);
}

Parsing JSON data and handling an Array

I am using Mantle to parse some JSON data from Yelp.
For each business returned I get an NSArray of categories. This would be an example:
yelpCategories = (
(
"Wine Bars",
"wine_bars"
),
(
"Ice Cream & Frozen Yogurt",
icecream
)
);
yelpCategories is the name of the array that I save. Later on I am trying to parse the array into a string:
NSMutableString *yelpCats = [[NSMutableString alloc] init];
for (NSObject * obj in business.yelpCategories)
{
[yelpCats appendString:[NSString stringWithFormat:#"%#,",[obj description]]];
}
The issue is with the above. I am being returned a string just as "(" so I must be accessing the array incorrectly. How can I correctly access each object, ideally I would be looking for the end string o be #"Wine Bars, Ice Cream & Frozen Yogurt".
EDIT
The categories array: (
(
Pubs,
pubs
)
)
FINAL EDIT - Proposed Solution
for (NSArray *cats in business.yelpCategories)
{
NSString *category = [cats objectAtIndex:0];
if ([category length] > 0) {
category = [category substringToIndex:[category length] - 1];
}
if (cats == business.yelpCategories.lastObject) {
[yelpCats appendString:[NSString stringWithFormat:#"%#",category]];
} else {
[yelpCats appendString:[NSString stringWithFormat:#"%#, ",category]];
}
}
cell.yelpCategories.text = yelpCats;
Using the description of the object gives you what you see in the debugger, which includes extra carriage returns.
What you want to do is something like:
yelpCats = [yelpCategories componentsJoinedByString:#", "];
#jeffamaphone 's answer is the correct and best way of doing things however what your doing will almost work, I think your just confused on the contents of the array.
The yelpCategories array is an array of strings so you don't need to call stringWithFormat or call the description method. In fact [obj description] will return a string so you didn't even need stringWithFormat in your example and you would have gotten the same output. To make your original method work change to:
NSMutableString *yelpCats = [[NSMutableString alloc] init];
for (id obj in business.yelpCategories)
{
//obj is a string so we can just append it.
[yelpCats appendString:obj]];
}
Also noticed I changed NSObject *obj to just id obj, this is the idiomatic way and shorthand way of declaring NSObjects in objective-c. In this example however I would actually use (NSString *category in business.yelpCategories) instead for better readability. In this case you are declaring to everyone that you expect each object in the array to be a string and then if you wanted to use NSString methods on it inside the loop then you don't have to cast it.
for (NSArray *cats in business.yelpCategories)
{
NSString *category = [cats objectAtIndex:0];
if ([category length] > 0) {
category = [category substringToIndex:[category length] - 1];
}
if (cats == business.yelpCategories.lastObject) {
[yelpCats appendString:[NSString stringWithFormat:#"%#",category]];
} else {
[yelpCats appendString:[NSString stringWithFormat:#"%#, ",category]];
}
}
cell.yelpCategories.text = yelpCats;

Adding successive words to array causes error

I am trying to create an array of values that when printed, will look like the following:
{
headerTitle = "#";
rowValues = (
""
);
} {
headerTitle = A;
rowValues = (
"Abaco Barb",
Abenauer,
"Australian Stockhorse",
);
} {
headerTitle = B;
etc…
The program fails with a "doesNotRecognizeSelector:" error on the statement indicated below.
The array is defined as:
NSMutableArray *words = [[NSMutableArray alloc]init];
THE RELEVANT CODE:
else
{
letterString = [[dataArray objectAtIndex:i] substringToIndex:1];
NSLog(#"lastLetter = %#",lastLetter);
NSLog(#"letterString = %#",letterString);
if ([lastLetter isEqualToString: letterString])
{
NSLog(#"before words, dataArray %#", [dataArray objectAtIndex:i]);
//(FAILS on the next instruction on adding [dataArray objectAtIndex:i] =
// Abenauer)
[words addObject:[dataArray objectAtIndex:i]];
NSLog(#"words - %#",words);
NSLog(#"after words");
}
else
{
NSMutableDictionary *row = [[NSMutableDictionary alloc] init];
[row setValue:lastLetter forKey: #"headerTitle"];
[row setValue: words forKey:#"rowValues"];
[content addObject:row];
NSLog(#"content - %#",content);
lastLetter = letterString;
words =[dataArray objectAtIndex:i];
NSLog(#"words - %#",words);
}
}
OUTPUT created before failure:
2014-03-21 11:37:42.967 EquineDiary[1864:a0b] lastLetter = #
2014-03-21 11:37:42.967 EquineDiary[1864:a0b] letterString = A
2014-03-21 11:37:42.968 EquineDiary[1864:a0b] content - (
{
headerTitle = "#";
rowValues = (
);
}
)
2014-03-21 11:37:54.434 EquineDiary[1864:a0b] words - Abaco Barb
2014-03-21 11:37:54.435 EquineDiary[1864:a0b] lastLetter = A
2014-03-21 11:37:54.436 EquineDiary[1864:a0b] letterString = A
2014-03-21 11:37:54.436 EquineDiary[1864:a0b] before words, dataArray Abtenauer
Thanking you in advance for your help.
NOTE 1:
The entire error is "CoreFoundation`-[NSObject(NSObject) doesNotRecognizeSelector:]:" Words is defined at the beginning of the Method, outside of the for loop. "Abaco Barb" is already in words when I am trying to add "Abtenauer" which is in [dataArray objectAtIndex:i].
All I am trying to do is put all names that begin with "A" into an array (words) until the word no longer begins with A at which time I write the words array to a row with the key "row values". A is written to the row with a key "header titles".
NOTE 2:
I have discovered the issue but don't know how to fix it. After I write the data to row I have the code " words =[dataArray objectAtIndex:i];" for the purpose of wiping the previous values (i.e. "A" values) so that I can start adding words which begin with the next letter (i.e. "B"). It doesn't like adding objects to words after I do this. Why is this? And what is the best way to wipe the values to begin again?
If you want a new array just create a new array.
words = [[NSMutableArray alloc] init]
It looks like Abenauer is not a string. It does not have quotes around it.

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;
}

Resources