NSMutableArray sorting

  • Hi, I have 2 NSMutableArray's and I need to sort one of them and I need the
    other one to follow along when the first one is sorted. Is there a way to do
    that using the array sorting functions?

    Thanks

    AC
  • On Sep 6, 2007, at 10:52 AM, Alex Cohen wrote:

    > Hi, I have 2 NSMutableArray's and I need to sort one of them and I
    > need the
    > other one to follow along when the first one is sorted. Is there a
    > way to do
    > that using the array sorting functions?

    Create a third array whose elements are first two array's elements
    "zippered" together:

    for (int i=0;i<[first count];i++) {
    [third addObject: [NSArray arrayWithObjects: [first objectAtIndex:
    i], [second objectAtIndex: i], nil]];
    }

    Sort that third array, using a function that basically extracts that
    first element:

    [third sortUsingFunction: zipperedCompare context: NULL];
    ...

    int zipperedCompare(id left, id right, void *context)
    {
    return [[left objectAtIndex:0] compare: [right objectAtIndex: 1]];
    }

    Finally unzipper the third array back to the first two

    for (int i=0;i<[third count];i++) {
    [first replactObjectAtIndex: i withObject: [[third objectAtIndex: i]
    objectAtIndex: 0]];
    [second replactObjectAtIndex: i withObject: [[third objectAtIndex:
    i] objectAtIndex: 1]];
    }

    One might be able to write a compare function that takes that second
    array as the context parameter and infer how the first array is going
    to get altered, but that probably either wouldn't work for all cases,
    would require internal knowledge of the sorting routine (which might
    break), and would require a whole lot of edge case testing to make
    sure that you are keeping the array.

    You could also just write your own sorting routine instead of using
    the built in sorting methods.

    Glenn Andreas                      <gandreas...>
      <http://www.gandreas.com/> wicked fun!
    quadrium | flame : flame fractals & strange attractors : build,
    mutate, evolve, animate
  • Sounds good. I ended up creating a class that encapsulates the 1 value from
    each array. Added accessors for those two vars and used sort descriptors.
    Works great.

    Thanks

    AC

    On 9/6/07 12:13 PM, "glenn andreas" <gandreas...> wrote:

    >
    > On Sep 6, 2007, at 10:52 AM, Alex Cohen wrote:
    >
    >> Hi, I have 2 NSMutableArray's and I need to sort one of them and I
    >> need the
    >> other one to follow along when the first one is sorted. Is there a
    >> way to do
    >> that using the array sorting functions?
    >
    > Create a third array whose elements are first two array's elements
    > "zippered" together:
    >
    > for (int i=0;i<[first count];i++) {
    > [third addObject: [NSArray arrayWithObjects: [first objectAtIndex:
    > i], [second objectAtIndex: i], nil]];
    > }
    >
    > Sort that third array, using a function that basically extracts that
    > first element:
    >
    > [third sortUsingFunction: zipperedCompare context: NULL];
    > ...
    >
    >
    > int zipperedCompare(id left, id right, void *context)
    > {
    > return [[left objectAtIndex:0] compare: [right objectAtIndex: 1]];
    > }
    >
    > Finally unzipper the third array back to the first two
    >
    > for (int i=0;i<[third count];i++) {
    > [first replactObjectAtIndex: i withObject: [[third objectAtIndex: i]
    > objectAtIndex: 0]];
    > [second replactObjectAtIndex: i withObject: [[third objectAtIndex:
    > i] objectAtIndex: 1]];
    > }
    >
    >
    >
    > One might be able to write a compare function that takes that second
    > array as the context parameter and infer how the first array is going
    > to get altered, but that probably either wouldn't work for all cases,
    > would require internal knowledge of the sorting routine (which might
    > break), and would require a whole lot of edge case testing to make
    > sure that you are keeping the array.
    >
    > You could also just write your own sorting routine instead of using
    > the built in sorting methods.
    >
    >
    > Glenn Andreas                      <gandreas...>
    > <http://www.gandreas.com/> wicked fun!
    > quadrium | flame : flame fractals & strange attractors : build,
    > mutate, evolve, animate
    >
    >
    >
  • On 6 Sep 2007, at 17:13, glenn andreas wrote:

    > On Sep 6, 2007, at 10:52 AM, Alex Cohen wrote:
    >
    >> Hi, I have 2 NSMutableArray's and I need to sort one of them and I
    >> need the
    >> other one to follow along when the first one is sorted. Is there a
    >> way to do
    >> that using the array sorting functions?
    >
    > Create a third array whose elements are first two array's elements
    > "zippered" together:

    Gosh, that seems like a complicated way to do it :-)

    I prefer having an array of indices; i.e.

      int n, count = [first count];
      for (n = 0; n < count; ++n)
        [third addObject:[NSNumber numberWithInt:n]];

    then

      [third sortUsingFunction:indexedCompare context:NULL];

    with

      static int indexedCompare(id left, id right, void *context)
      {
        return [[first objectAtIndex:[left intValue]]
                compare:[first objectAtIndex:[right intValue]]];
      }

    (This sorts the indices based on the contents of the first array).

    Often you don't need to actually re-sort the arrays themselves
    afterwards; you can just step through the index array and grab
    objects at the indices you extract.  You can also make this more
    efficient, e.g. by using a C array or a C++ vector for your indices,
    or by writing a specialised NSArray subclass specifically for holding
    arrays of integers.

    Kind regards,

    Alastair.

    --
    http://alastairs-place.net
previous month september 2007 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
Go to today