如何验证多维 NSArray 结构?

How to validate multi-dimentional NSArray structure?

假设我们有 NSArrayNSArrayNSNumber 是这样的:

NSArray *transform = @[
                       @[@1, @0, @1],
                       @[@0.01f, @1, @0],
                       @[@1, @0, @1.1f]
                       ];

并且我们要根据 "3x3 NSArray of NSNumber" 的规则验证其结构。 我开发的解决方案是这样的:

BOOL __block validTransform = YES;
if (transform && [transform count] == 3) {
    [transform enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSLog(@"object: %lu of aClass: %@", idx, [obj class]);
        if ([obj isKindOfClass:[NSArray class]] && [obj count] == 3) {
            [obj enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                NSLog(@"- object: %lu of aClass: %@", idx, [obj class]);
                if (![obj isKindOfClass:[NSNumber class]]) {
                    validTransform = NO;
                    *stop = YES;
                }
            }];
        } else {
            validTransform = NO;
            *stop = YES;
        }
    }];
} else validTransform = NO;

NSAssert(validTransform == YES, @"Transform must be 3x3 NSArray of NSNumber");
if (!validTransform) return ...;

...我的问题是:有比这更简单的方法吗?

我可以将矩阵更改为向量以减少一维,但我更喜欢比较输入矩阵的结构(而不​​是值)和具有相同数据类型的一些参考矩阵。

您所拥有的一切都有效,因此您不必为此担心。问题足够小,您应该没有性能问题。如果内部循环失败,您可以通过中断外部循环来稍微提高效率,尽管只有测试才能证明这是否真的有很大帮助。

如果您担心代码的复杂性,请添加一个小评论。

您可以将代码拆分为执行每个级别的方法,但实际上您所拥有的可能是您问题的解决方案,因为它不是标准验证,而是自定义结构。

主要的替代方案是与数组数组(如浮点数结构)不同的数据结构。

我假设这是一个变换矩阵?

NSArrays 和 NSNumbers 是一个糟糕的选择。使用固定大小的 C 数组或结构要好得多。 (矩阵)

NSNumbers 是不可变的,因此您必须在值发生变化时创建一个新的。

遍历外层数组到达内层数组,然后从内层数组中获取对象需要调用方法,速度很慢。将 NSNumber 转换为数值标量也是一种方法调用。

通常变换矩阵应用于数千甚至数百万个点,因此使用 NSArrays 的开销会增加。看一下CATransform3D的定义(是一个4x4的矩阵,不过还是给你思路。。。)

struct CATransform3D
{
  CGFloat m11, m12, m13, m14;
  CGFloat m21, m22, m23, m24;
  CGFloat m31, m32, m33, m34;
  CGFloat m41, m42, m43, m44;
};

实际上是一个扁平的一维浮点数系列,处理起来更简单高效