Array Indexing Question

Discussion in 'Mac Programming' started by Alkerak, Jul 22, 2011.

  1. Alkerak macrumors newbie

    Joined:
    Jul 20, 2011
    #1
    I was working on detecting whitespaces in my array when I stumbled upon something very interesting.
    I was thinking an array is something like [0][1][2][3][4] ...

    However ... when I display all my indexes it seems each individual character/object/string has a unique index.

    So it would follow something like this:

    [t][e][t] = [0][1][2][0]

    Is it normal? Should it not be [0][1][2][3]?
    I dont complain since this makes my whitespace ignoring routine more easy because each whitespace has the same index ... but it does make one wonder.
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    This doesn't make sense. Show us some code that led to this understanding. Your initial understanding is correct.

    -Lee
     
  3. Alkerak thread starter macrumors newbie

    Joined:
    Jul 20, 2011
    #3
    Here is the code ... I dont know what happened but it seems more easy to tackle code this way :D

    Code:
    #import <Foundation/Foundation.h>
    #import "CustomFunctions.h"
    
    int main (int argc, const char * argv[])
    {
    
       NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
       
       //this is the string that is captured by the keyboard
       NSString *string = ReadFromStandardInput();
       
       //length of the captured word
       NSUInteger intLength = [string length];
       
       //create an array based on the length of the captured word minus the newline character (length - 1)
       NSMutableArray *myArray = [[[NSMutableArray alloc] initWithCapacity:(intLength - 1)] autorelease];
    
       //break string into single characters and store them as an array
       for (int i = 0; i <= (intLength - 1); i++)
       {
          NSString *singleCharString = [string substringWithRange:NSMakeRange(i, 1)];
          [myArray insertObject:singleCharString atIndex:i];
       }
       
       
       for (NSString *string in myArray)
       {
          NSLog(@"%lu", [myArray indexOfObject:string]);
       }
    
       [pool drain];
       return 0;
    }
    
     
  4. JoshDC macrumors regular

    Joined:
    Apr 8, 2009
    #4
    Documentation should be the first place to look if you don't understand something's behaviour.

    From NSArray's indexOfObject:

    So it returns the index of the first @"t".

    NSMutableArray and NSString have apt methods for removing all instances of a given object/substring, so there's no need for you to do manual traversal to remove whitespace.
     
  5. Ara- macrumors newbie

    Joined:
    Apr 24, 2010
    #5
    indexOfObject finds the lowest index which values is equal to the one in the parameter. Thus, the invocation with the string 't' returns the index 0.

    Try:

    Code:
    NSUInteger count = [myArray count];
    for(NSUInteger i = 0 ; i < count; i++){
         NSLog(@"%lu", [myArray objectAtIndex:i]);
    } 
    
     
  6. PatrickCocoa macrumors 6502a

    Joined:
    Dec 2, 2008
    #6
    Some / Many / Most ?

    Some (many? most?) problems have already been solved by Apple's Cocoa team. That is, in some (many? most?) cases what you want to do has already been thought of and implemented. Learn to look in the class documentation to see if there's a method that does what you want.
     
  7. Alkerak thread starter macrumors newbie

    Joined:
    Jul 20, 2011
    #7
    I looked into the documentation but it is not what I wish to be found there. All I want is to find out the index position of a whitespace in my object so as to ignore it in some shuffle algorithm. I found no function that does this sadly.
     
  8. ChOas macrumors regular

    Joined:
    Nov 24, 2006
    Location:
    The Netherlands
    #8
    Does that mean you want to shuffle the letters of individual words in a sentence ? or what ?

    It would be easier to split the sentence in words (splitting on space) shuffling those and then concatenating them again.
     
  9. jiminaus, Jul 23, 2011
    Last edited: Jul 23, 2011

    jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #9
    If you goal is to scramble the words in a sentence, right? And you don't want to mix up the letters of the words, that is you only want to scramble the letters within a word, right?

    Then I would start by sending componentsSeparatedByCharactersInSet: to the input string to divide the string into words. Then I would iterate over the array, and scramble the letters in each word ignoring potential empty strings building by a new array. Then rebuild the string by sending componentsJoinedByString: to the new array.

    You see there's lots of build-in support for your solution.

    EDIT: What ChOas said.
     
  10. Alkerak thread starter macrumors newbie

    Joined:
    Jul 20, 2011
    #10
    It's still a problem though since this causes the array to store individual substrings, not characters. My algorithm works only on shuffling individual array elements around.
    I would need a dynamically created number of arrays at startup depending on the number of words my sentence has and store each character in the word in a separate array, shuffle it and then rejoin them in the same order.
     
  11. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #11
    Break the sentence into words (one array). Create another mutable array. Take words out of the first array one at a time. Shuffle the word. You already know how to do that, so break it down and put it in a separate method that takes a word NSString and returns a shuffled word NSString. Add the shuffled word to the second array. Repeat for entire first array. What is the resulting second array?

    Even if you needed a dynamic number of arrays, you could store them in another array: an array of arrays. You don't need that here, but it might be worthwhile trying it, after you get the simpler version working correctly
     
  12. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #12
    You are thinking about this wrong. Here are some sample steps:
    Get input string
    Divide input string into words using componentsSeparatedByCharactersInSet:
    Loop over the array, passing each word to a subroutine that returns a shuffled version.
    Store the result in an array OR append the result (and a space?) to a result string.
    If you stored results to an array, join them with: componentsJoinedByString:
    Display result

    Your "algorithm" to shuffle still works, you just encapsulate it in a function that accepts a string with a word, and returns a shuffled version.

    -Lee

    Edit: Basically what chown33 said.
     
  13. Alkerak thread starter macrumors newbie

    Joined:
    Jul 20, 2011
    #13
    I understand what you say and the logic is very simple, however it cannot be applied since my simple shuffle routine works on individual elements on an array.

    This is my routine:

    Code:
    void ScrambleArray(NSMutableArray *array)
    {
       srandom((unsigned int)time(NULL));
       NSUInteger count = [array count];
       for (int i = 0; i < count; ++i)
       {
          NSUInteger numberOfElements = count - i;
          NSUInteger n = (random() % numberOfElements) + i;
          [array exchangeObjectAtIndex:i withObjectAtIndex:n];
       }
    }
     
  14. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #14
    You're being very inflexible, which is going to make many programming tasks very difficult. You have a string. You want an array of single-char strings or chars. How might you get a resulting array into a string?

    This routine needs 2-5 lines to get you where you want to go.

    -Lee
     
  15. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #15
    You're not thinking this through.

    The first thing to do is break the sentence (multiple words separated by spaces) into an array of words. Each word will be an NSString.

    The goal is to shuffle the letters of each word to produce another NSString.

    To do that, take the first word from the array. Break it down into an NSMutableArray with one letter in each NSString. You've already posted code that can do this. It's in post #3, at this comment:
    Code:
       //break string into single characters and store them as an array
    
    Now, shuffle that array. You've just posted code that does this.

    At this point, what is the resulting NSMutableArray? It's an array of single letters, each one in an NSString. The letters have been shuffled.

    Next, combine the letters in the shuffled array (in order) into a single NSString. There are several ways you can do that, none of them difficult to figure out or write code for.

    The resulting NSString now contains the original word with its letters shuffled. Add it to an NSMutableArray.

    Repeat the above for each word from the separated-words array.

    At the end, the NSMutableArray will hold words with letters shuffled, but in the same order as the original sentence's word order. Combine them with a space between each word.
     
  16. JoshDC macrumors regular

    Joined:
    Apr 8, 2009
    #16
    Not trying to make this more complicated than it needs to be, but Apple have provided 'better' ways to split by words and characters. While the approach provided previously works fine in most cases (especially English), there are cases where words and printed characters aren't as simple as space separated strings and length one substrings.

    NSString has a method called:

    Code:
    enumerateSubstringsInRange:options:usingBlock:
    Which can better split on words or printed characters by passing NSStringEnumerationByWords or NSStringEnumerationByComposedCharacterSequence as the option. It can also take into account the user's locale setting by bitwise ORing the option with NSStringEnumerationLocalized.

    For example:

    Code:
        NSMutableArray *words = [NSMutableArray array];
        
        [inputString enumerateSubstringsInRange:NSMakeRange(0, [inputString length])
                                        options:NSStringEnumerationByWords | NSStringEnumerationLocalized
                                     usingBlock:
         ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
              [words addObject:substring];
         }];
    
    Again, the previously offered approach should work fine for you. Just be aware words and characters can be rather complex, and this method is here to help you.
     
  17. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #17
    If you want to get the individual characters of an NSString object, send it getCharacters:range:.
     
  18. PatrickCocoa macrumors 6502a

    Joined:
    Dec 2, 2008
    #18
    Actually, we're nice guys

    Alkerak, I hope you don't feel we're ganging up on you unfairly. I posted a brief comment earlier about Cocoa and Apple. To reiterate:

    Apple is smarter than you.

    Cocoa is in charge, not you.

    Apple has solved all of the problems ever conceived for all programs ever.

    Programing has changed from byte and character manipulations using clever algorithms to finding what method Cocoa has buried your solution in.

    Of course, the above is a considerable overstatement. But it's a good starting point.
     
  19. Alkerak thread starter macrumors newbie

    Joined:
    Jul 20, 2011
    #19
    Thanks, I finally understood what you guys meant! I had to break the task down in sufficient small pieces. Sometimes I am thinking to abstract :)
     
  20. Alkerak thread starter macrumors newbie

    Joined:
    Jul 20, 2011
    #20
    It's ok, I understand what you mean. No hard feelings.
     

Share This Page