@distinctUnionOfObjects changes the order of objects?

  • Hi all,

      I have the following relatively simple problem. I
    have an NSArray that has two entries. Each entry is a
    dictionary with two keys, @"ProgramCode" and
    @"ProgramName". Actually it has more keys, but let's
    not worry about them. The values of both keys are
    NSStrings. What I want is, given a string aCode, much
    aCode among the @"ProgramCode" key in the matrix, and
    return the corresponding value of the key
    @"programName". In my case in particular, lets say
    that the first entry of the array has
    ProgramCode="MCLY" and programName="Macaulay 2", while
    the second entry has ProgramCode="PARI" and
    programName="PARI/GP". What I thought should work was:

    NSArray *codeList = [myArray
    valueForKeyPath:@"@distinctUnionOfObjects.ProgramCode"];
    unsigned int indexOfCode = [codeList
    indexOfObject:aCode];
    NSString *aProgramName = [[myArray
    objectAtIndex:index] valueForKey:@"ProgramName"];

    What happens when I try to debug this, is that
    codeList contains the codes in the reverse order than
    the order they appeared in the array, i.e. PARI comes
    first, and MCLY second. Of course the result of this
    is that the index information I get out of this is
    useless.
    Is this something to be expected? I can't rely on
    @distinctUnionOfObjects not to mess up the order of
    things?
    Is there a better way to accomplish what I am trying
    to do, without actually writing my own loop that goes
    through the array entries?

    Haris


    __________________________________
    Do you Yahoo!?
    Meet the all-new My Yahoo! - Try it today!
    http://my.yahoo.com
  • On Dec 20, 2004, at 5:03 PM, Harilaos Skiadas wrote:

    > Hi all,
    >
    > I have the following relatively simple problem. I
    > have an NSArray that has two entries. Each entry is a
    > dictionary with two keys, @"ProgramCode" and
    > @"ProgramName". Actually it has more keys, but let's
    > not worry about them. The values of both keys are
    > NSStrings. What I want is, given a string aCode, much
    > aCode among the @"ProgramCode" key in the matrix, and
    > return the corresponding value of the key
    > @"programName". In my case in particular, lets say
    > that the first entry of the array has
    > ProgramCode="MCLY" and programName="Macaulay 2", while
    > the second entry has ProgramCode="PARI" and
    > programName="PARI/GP". What I thought should work was:
    >
    > NSArray *codeList = [myArray
    > valueForKeyPath:@"@distinctUnionOfObjects.ProgramCode"];
    > unsigned int indexOfCode = [codeList
    > indexOfObject:aCode];
    > NSString *aProgramName = [[myArray
    > objectAtIndex:index] valueForKey:@"ProgramName"];
    >
    you misunderstand what @distinctUnionOfObjects gives you

      it'll give you an array of uniqued values in ProgramCode, and you
    can't guarantee the order to be preserved

      you could keep a separate NSDictionary that contains the ProgramCode
    string as the key, and the object in the array as the value. then you
    could do the lookup in two stages (look up ProgramCode in the
    dictionary, and then get ProgramName from the value returned
  • --- Scott Anguish <scott...> wrote:

    > you misunderstand what @distinctUnionOfObjects gives
    > you
    >
    > it'll give you an array of uniqued values in
    > ProgramCode, and you
    > can't guarantee the order to be preserved

    I see. So in case there are dublicates in ProgramCode,
    it will only keep one of them? Hence there isn't even
    a notion of order in the first place.

    > you could keep a separate NSDictionary that
    > contains the ProgramCode
    > string as the key, and the object in the array as
    > the value. then you
    > could do the lookup in two stages (look up
    > ProgramCode in the
    > dictionary, and then get ProgramName from the value
    > returned
    >
    This happens way too often in my program, and that's
    probably a design flaw but for now I am trying to get
    it to work, and I'd rather not do the two stage thing
    all the time. Plus, I often just want the list of the
    ProgramCode's in the same order each time.
    I ended up adding a category on NSArray with methods
    valuesForKey:(NSString *)aKey, which returns an array
    with the values for aKey of the objects of the array,
    and objectWithValue:(id)aValue forKey:(NSString
    *)aKey, which finds and returns the first object in
    the array with value aValue for key aKey. Seems to
    work fine for now, hopefully I haven't made any very
    serious mistakes. Here is their code:

    - (id)objectWithValue:(id)aValue forKey:(NSString
    *)aKey
    {
    int i;
    unsigned int count = [self count];
    id anItem;
    for (i = 0; i < count; i++) {
      anItem = [self objectAtIndex:i];
      if ([[anItem valueForKey:aKey] isEqual:aValue])
      return anItem;
    }
    return nil;
    }

    - (NSArray *)valuesForKey:(NSString *)aKey
    {
    NSMutableArray *tempArray = [NSMutableArray array];
    int i;
    unsigned int count = [self count];
    for (i = 0; i < count; i++) {
      [tempArray addObject:[[self objectAtIndex:i]
    valueForKey:aKey]];
    }
    return tempArray;
    }

    Thanks,
    Haris


    __________________________________
    Do you Yahoo!?
    All your favorites on one personal page – Try My Yahoo!
    http://my.yahoo.com
previous month december 2004 next month
MTWTFSS
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
Go to today