如何验证多维 NSArray 结构?
How to validate multi-dimentional NSArray structure?
假设我们有 NSArray
的 NSArray
的 NSNumber
是这样的:
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;
};
实际上是一个扁平的一维浮点数系列,处理起来更简单高效
假设我们有 NSArray
的 NSArray
的 NSNumber
是这样的:
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;
};
实际上是一个扁平的一维浮点数系列,处理起来更简单高效