title: Nested NSArray filtering
body: <p>I have the need to obtain the maximum value of a property of a collection of custom objects of the same class. The objects are stored in a NSArray, and the property happens to be another NSArray of numbers.</p>
  <p>Let me explain in detail:</p>
  <pre><code>NSArray *samples; // of CMData, 4000 elements
  </code></pre>
  <p>CMData is a class that models a sample, for a specific moment in time, of a set of different channels that can have different values.</p>
  <pre><code>@interface CMData : NSObject
  @property (nonatomic) NSUInteger timeStamp;
  @property (nonatomic, strong) NSArray *analogChannelData; // of NSNumber, 128 elements
  @end
  </code></pre>
  <p>(I have stripped other properties of the class not relevant to the question)</p>
  <p>So for example, sample[1970] could be:</p>
  <pre><code>sample.timeStamp = 970800
  sample.analogChannelData = &lt;NSArray&gt;
      [
      [0] = @(153.27)
      [1] = @(345.35)
      [2] = @(701.02)
      ...
      [127] = @(-234.45)
      ]
  </code></pre>
  <p>Where each element [i] in the analogChannelData represents the value of that specific channel i for the timeStamp 970800</p>
  <p>Now I want to obtain the maximum value for all the 4000 samples for channel 31. I use the following code:</p>
  <pre><code>NSUInteger channelIndex = 31;
  NSMutableArray *values = [[NSMutableArray alloc] init]; // of NSNumber
  // iterate the array of samples and for each one obtain the value for a 
  // specific channel and store the value in a new array
  for (CMData *sample in samples) {
      [values addObject:sample.analogChannelData[channelIndex]];
  }
  // the maximum 
  NSNumber *maxValue = [values valueForKeyPath:@&quot;@max.self&quot;];
  </code></pre>
  <p>I want to replace this programming structure by a filter through an NSPredcicate or use valueForKeyPath: to obtain the maximum of the data I need.</p>
  <p>Anyone knows how to do this without a for loop? Just using NSPredicates and/or valueForKeyPath?</p>
  <p>Thank you very much in advance for your help.</p>
  <h2>Update 1</h2>
  <p>Finally I benckmarked the for-loop version against the keyPath version (see accepted answer) and it runs much faster so it is better to go with a for loop.
  Recalling some lessons from my algorithms classes, I implemented an even faster version that doesn't need an array to store the values. I just iterate over the selected channel and just choose the maximum in each iteration. This is by far the fastest version.</p>
  <p>So:</p>
  <ul>
  <li>version 1: for loop (see code above)</li>
  <li>version 2: version with custom property (see selected answer from Marcus, update 2)</li>
  <li>version 3: new code</li>
  </ul>
  <p>Code for version 3:</p>
  <pre><code>NSUInteger channelIndex = 31;
  NSNumber *maxValue = @(-INFINITY);
  for (CMTData *sample in samples) {
      NSNumber *value = sample.analogChannelData[channelIndex];
      if (value) { // I allow the possibility of NSNull values in the NSArray
          if ([value compare:maxValue] == NSOrderedDescending)
              maxValue = value;
      }
  }
  // the maximum is in maxValue at the end of the loop
  </code></pre>
  <p>Performance:</p>
  <p>After 20.000 iterations in iOS simulator:</p>
  <ul>
  <li>Version 1: 12.2722 sec.</li>
  <li>Version 2: 21.0149 sec.</li>
  <li>Version 3:  5.6501 sec.</li>
  </ul>
  <p><strong>The decision is clear. I'll use the third version.</strong></p>
  <h2>Update 2</h2>
  <p>After some more research, it is clear to me now that KVC does not work for infividual elements in the inner array. See the following links: <a href="https://stackoverflow.com/questions/3081632/kvc-with-nsarrays-of-nsarrays?rq=1">KVC with NSArrays of NSArrays</a> and <a href="https://stackoverflow.com/questions/17387553/objective-c-kvc-collection-accessor-patterns-for-to-many-properties-how-can-i">Collection Accessor Patterns for To-Many Properties</a></p>
  <p>Anyway because I wanted to compute the maximum of the elements it is better to iterate the array than use some tricks to make KVC work.</p>