我在核心数据中有一个简单的数据模型:一个名为" Employee"有几个参考:
现在我想计算任何员工的直接/间接报告总数。所以我创建了一个类别Employee + Statistics
- (NSUInteger) totalNumberOfSubordinates {
NSUInteger numberOfSubordinates= [self.directReports count];
for (Employee *e in self.directReports) {
numberOfSubordinates += e.totalNumberOfSubordinates ;
}
return numberOfSubordinates;
}
这是一个问题:当我尝试查找CEO的totalNumberOfSubordinates时,这种方法是否会自动触发所有错误?假设数据经常变化,即新员工加入,现有员工退出,是否有更好的方法?
谢谢!
答案 0 :(得分:1)
当我尝试查找CEO的totalNumberOfReports时,这种方法会自动触发所有错误吗?
是
有更好的方法吗?
是的,但您可能需要更改模型
您当前的解决方案很可能会触发O(N)故障(沿着主管树向下)。
一个例子是将总计数存储为Employee
实体的属性(例如totalSubordinates
)。
当员工supervisor
被设置时,更新该主管人数(他将依次更新他的主管人数)。
看起来应该是这样的:
//NOT TESTED
- (void) setSupervisor:(Employee*)newSup
{
if (newSup == self.supervisor) {
return;
}
[self.supervisor changeTotalSubordinatesBy:-self.totalSubordinates];
[newSup changeTotalSubordinatesBy:self.totalSubordinates];
[self willChangeValueForKey:@"supervisor"];
[self setPrimitiveValue:newSup forKey:@"supervisor"];
[self didChangeValueForKey:@"supervisor"];
}
- (void) changeTotalSubordinatesBy:(NSInteger)amount
{
if (amount == 0) {
return;
}
self.totalSubordinates += amount;
[self.supervisor changeTotalSubordinatesBy:amount];
}
- (void) prepareForDeletion
{
self.supervisor = nil;
}
通过这种方式,您可以上监督树(假设监管人员少于雇员),并且您发现O(N)故障的可能性非常低。
此外,您已将totalSubordinates
的访问时间更改为O(1)[内存访问],并将复杂性移至更改员工主管(插入,移动,删除)的时间< / p>
另一种方法是保留每个Employee
的整个主管链并发出一个计数请求(这里你将使插入过程复杂化,“主 - 主管”可能与所有其他下属有关系,虽然你可以放弃反向关系......)
在这种情况下,复杂性将是O(1)[从磁盘获取]