【问题标题】:How to find the median value of NSNumbers in an NSArray?如何在 NSArray 中找到 NSNumbers 的中值?
【发布时间】:2010-07-14 20:44:54
【问题描述】:

我正在尝试计算 NSArray 中一组(小)NSNumber 的中位数。 NSArray 中的每个对象都是一个 NSNumber。

这是我正在尝试的,但它不起作用:

NSNumber *median = [smallNSArray valueForKeyPath:@"@median.floatValue"];

【问题讨论】:

    标签: iphone objective-c cocoa key-value


    【解决方案1】:
    NSArray *sorted = [smallNSArray sortedArrayUsingSelector:@selector(compare:)];    // Sort the array by value
    NSUInteger middle = [sorted count] / 2;                                           // Find the index of the middle element
    NSNumber *median = [sorted objectAtIndex:middle];                                   // Get the middle element
    

    你可以变得更漂亮。例如,具有偶数个数字的集合的中位数在技术上是中间 两个 数字的平均值。您还可以将其包装成一个简洁的单行方法,放在NSArray 的一个类别中:

    @interface NSArray (Statistics)
    - (id)median;
    @end
    
    @implementation NSArray (Statistics)
    
    - (id)median
    {
        return [[self sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:[self count] / 2];
    }
    
    @end
    

    【讨论】:

      【解决方案2】:

      对于对这个函数有特殊需求的任何人,这里有一个 NSArray 上的类别方法,它可以处理奇数和偶数个元素:

      NSARRAY 类别方法

      - (float)median {
          if (self.count == 1) return [self[0] floatValue];
      
          float result = 0;
          NSUInteger middle;
      
          NSArray * sorted = [self sortedArrayUsingSelector:@selector(compare:)];
          if (self.count % 2 != 0) {  //odd number of members
              middle = (sorted.count / 2);
              result = [[sorted objectAtIndex:middle] floatValue];
          }
          else {
              middle = (sorted.count / 2) - 1;
              result = [[@[[sorted objectAtIndex:middle], [sorted objectAtIndex:middle + 1]] valueForKeyPath:@"@avg.self"] floatValue];
          }
          return result;
      }
      

      测试

      NSArray * singleElement = @[@1];
      NSArray * oddNumberOfElements = @[@3, @5, @7, @12, @13, @14, @19, @20, @21, @22, @23, @29, @39, @40, @56];
      NSArray * evenNumberOfElements = @[@3, @5, @7, @12, @13, @14, @19, @20, @21, @22, @23, @29, @40, @56];
      
      NSLog(
          @"oddNumberOfElements: %f, evenNumberOfElements: %f singleElement: %f",
          [oddNumberOfElements median], [evenNumberOfElements median], [singleElement median]
      );
      //oddNumberOfElements: 20.000000, evenNumberOfElements: 19.500000 singleElement: 1.000000
      

      【讨论】:

      • 您在奇怪的情况下选择了错误的索引,甚至更糟;当数组长度为 1 时代码崩溃。
      • @JKvr,谢谢!粗心...修改了方法并添加了测试代码。
      【解决方案3】:

      Swift 扩展

      extension Array where Element: Comparable {
      
        var median: Element {
          return self.sort(<)[self.count / 2]
        }
      
      }
      

      【讨论】:

      • 正如上面所说的,对于偶数个项目,这将无法正常工作。
      猜你喜欢
      • 2013-04-02
      • 1970-01-01
      • 2012-08-08
      • 2011-03-06
      • 1970-01-01
      • 2010-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多