0

I have a NSArray that looks like this:

NSArray *array = {@"1.100.2", @"23465343", @"1.100.1", @"46535334", @"1.0.03", @"24353454" ...};

I need to pair every 2 strings into an array within an array like this:

NSArray *pairedArray = {{@"1.100.2", @"23465343"}, {@"1.100.1", @"46535334"}, {@"1.0.03", @"24353454"}, ...};

The array is dynamic.

I think there's a for statement I can use but can't remember. Something like for (uint i = 0; i < len - 1; i += 2)

Any help would be appreciated.

CokePokes
  • 941
  • 3
  • 12
  • 25
  • See also https://stackoverflow.com/questions/26395766/swift-what-is-the-right-way-to-split-up-a-string-resulting-in-a-string-wi – matt Mar 25 '21 at 17:23

1 Answers1

1

Here is something that tries to be fast, by using the array's iterator and by making heavy use of arrayWithCapacity.

        NSArray *array = @[ @"1.100.2", @"23465343", @"1.100.1", @"46535334", @"1.0.03", @"24353454" ];
        NSUInteger countPerPair = 2;
        NSMutableArray * pair = [NSMutableArray arrayWithCapacity:countPerPair];
        NSMutableArray * pairedArray = [NSMutableArray arrayWithCapacity:( array.count + countPerPair / 2 ) / countPerPair];

        for ( NSObject * i in array )
        {
            if ( pair.count == countPerPair )
            {
                [pairedArray addObject:pair];
                pair = [NSMutableArray arrayWithCapacity:countPerPair];
            }

            [pair addObject:i];
        }

        if ( pair.count )
        {
            [pairedArray addObject:pair];
        }
skaak
  • 2,988
  • 1
  • 8
  • 16
  • While this does work, I'm seeing that some pairs are swapped. for instance: NSArray *pairedArray = {{@"1.100.2", @"23465343"}, {@"46535334", @"1.100.1"}, {@"1.0.03", @"24353454"}, ...}; edit: it looks like they are swapping order every other pair. – CokePokes Mar 25 '21 at 20:36
  • @CokePokes Ooops! There is a serious bug in that code. I've fixed it, should be better now. – skaak Mar 26 '21 at 06:23
  • 1
    Yup, works! Thanks mate. Marked as solved! – CokePokes Mar 26 '21 at 20:55
  • Not that the performance really matters for this small of a data set, but I'd lean away from using mutable arrays. Creating the sub-arrays all at once as NSArray instances is both slightly faster, but also safer. If your data model is intended to not be mutable, then the storage objects should be mutable. – bbum Mar 26 '21 at 21:10
  • @bbum you mean create the pairs something like ```[NSArray arrayWithObjects:a,b,nil]```? I did consider that but then you are bound to pairs with 2 - I made mine specifically to be variable which means you need mutable. Not sure what you mean with `Creating the sub-arrays all at once as NSArray instances` but curious? Can you explain? – skaak Mar 27 '21 at 08:30
  • @skaak I wrote a quick example that declares `NSObject *objs[countPerPair]`, filling that array using `objectAtIndex:` and then calling `+arrayWithObjects:count:`. – bbum Mar 30 '21 at 20:18
  • @bbum oh ok, so you use C style array and then convert that into fixed size Objective-C style array. I *think* with using `arrayWithCapacity` as I did you'd get similar performance. Oh well, may ways to skin a cat. – skaak Mar 31 '21 at 07:14
  • @skaak It is simpler than that. No need to use arrayWithCapacity: at all. `+arrayWithObjects:count:` pulls N object pointers from the C array and shoves it into an immutable NSArray. Definitely many ways to skin a cat. :). If one wanted to totally prematurely optimize, there is probably a CFArray API that'd be even faster. – bbum Apr 02 '21 at 00:17