简体   繁体   English

将NSArray与NSMutableArray进行比较,将delta对象添加到NSMutableArray

[英]Compare NSArray with NSMutableArray adding delta objects to NSMutableArray

I have an NSMutableArray that is populated with objects of strings. 我有一个NSMutableArray ,其中填充了字符串对象。 For simplicity sake we'll say that the objects are a person and each person object contains information about that person. 为简单起见,我们会说对象是一个人,每个人对象都包含有关该人的信息。

Thus I would have an NSMutableArray that is populated with person objects: 因此,我将有一个填充了person对象的NSMutableArray:

person.firstName
person.lastName
person.age
person.height

And so on. 等等。

The initial source of data comes from a web server and is populated when my application loads and completes it's initialization with the server. 最初的数据源来自Web服务器,并在我的应用程序加载时填充并完成它与服务器的初始化。 Periodically my application polls the server for the latest list of names. 我的应用程序会定期轮询服务器以获取最新的名称列表。

Currently I am creating an NSArray of the result set, emptying the NSMutableArray and then re-populating the NSMutableArray with NSArray results before destroying the NSArray object. 目前我正在创建结果集的NSArray ,清空NSMutableArray ,然后在销毁NSArray对象之前使用NSArray结果重新填充NSMutableArray

This seems inefficient to me on a few levels and also presents me with a problem losing table row references which I can work around, but might be creating more work for myself in doing so. 这对我来说在几个层面上看起来效率低下,并且还给我一个丢失表行参考的问题,我可以解决这个问题,但可能会为我自己创造更多的工作。

The inefficiency seems to be that I should be able to compare the two arrays and end up with a filtered NSArray . 低效率似乎是我应该能够比较两个数组并最终得到过滤的NSArray I could then add the filtered set to the NSMutableArray . 然后我可以将过滤的集添加到NSMutableArray This would mean that I can simply append new data to the NSMutableArray instead of throwing everything out and re-populating. 这意味着我可以简单地将新数据附加到NSMutableArray而不是丢弃所有内容并重新填充。

Conversely I would need to do the same filter in reverse to see if there are records that need removing from the NSMutableArray . 相反,我需要反向执行相同的过滤器,以查看是否有需要从NSMutableArray删除的记录。

Is there any method to do this in a more efficient manner? 有没有办法以更有效的方式做到这一点? Have I overlooked something in the docs some place that refers to a simpler technique? 我是否忽略了一些涉及更简单技术的文档中的某些内容?

I have a problem when I empty the NSMutableArray and re-populate in that any referencing tables lose their selected row state. 当我清空NSMutableArray并重新填充时,我遇到了一个问题,即任何引用表都会丢失其选定的行状态。 I can track it and re-select it, but my theory is that using some form of compare and adding objects and removing objects instead of dealing with the whole array in one block might mean I keep my row reference (assuming the item isn't deleted of course). 我可以跟踪它并重新选择它,但我的理论是使用某种形式的比较和添加对象并删除对象而不是在一个块中处理整个数组可能意味着我保留我的行引用(假设该项目不是当然删除了)。

Any suggestions or help much appreciated. 任何建议或帮助非常感谢。

Update 更新

Would it be just as fast to do a fast enumeration over each comparing each line item as I go? 在我每次比较每个订单项时,快速枚举是否同样快? It seems like an expensive operation, but with the last fast enumeration code it might be pretty efficient... 这似乎是一个昂贵的操作,但使用最后的快速枚举代码,它可能非常有效...

Solution

I ended up going with Abizem's suggestion. 我最终选择了Abizem的建议。 Creating the mutable copy of the array and a copy of the object appears to be the slightly faster approach than using sbooth's solution when dealing with large sets of data. 在处理大量数据集时,创建数组的可变副本和对象副本似乎比使用sbooth解决方案稍快一些。 Both worked great, I just got more of an edge by using the mutable copy approach. 两者都很好用,我通过使用可变复制方法获得了更多优势。 That being said, it did open my eyes up to NSSet where I hadn't looked before. 话虽如此,它确实让我睁开眼睛看着我以前没有看过的NSSet。

Thanks for the feedback. 感谢您的反馈。

You can use NSSet to do this type of thing easily (assuming your person objects are unique): 您可以使用NSSet轻松地执行此类操作(假设您的person对象是唯一的):

NSSet *existingItems = [NSSet setWithArray:existingItemArray];
NSSet *newItems = /* Get the new items from the server */

// Determine which items were removed
NSMutableSet *removedItems = [NSMutableSet setWithSet:existingItems];
[removedItems minusSet:newItems];

// Determine which items were added
NSMutableSet *addedItems = [NSMutableSet setWithSet:newItems];
[addedItems minusSet:existingItems];

// Modify the original array
[existingItemArray removeObjectsInArray:[removedItems allObjects]];
[existingItemArray addObjectsFromArray:[addedItems allObjects]];

I'd be surprised if the performance isn't decent, as I'm sure the implementation is optimized. 如果性能不合适,我会感到惊讶,因为我确信实现已经过优化。

Two points. 两点。

  1. The new NSArray contains all the data you need to show. 新的NSArray包含您需要显示的所有数据。 Which is why you are adding and deleting from the NSMutableArray to match the new one. 这就是为什么要从NSMutableArray添加和删除以匹配新的。
  2. You don't want to lose the selected state of the rows in your table. 您不希望丢失表中行的选定状态。

Here're my suggestions 这是我的建议

  1. Rather than emptying the NSMutableArray and repopulating it with the new Array; 而不是清空NSMutableArray并用新数组重新填充它; why not create a mutableCopy of the NSArray and set that as your new NSMutableArray? 为什么不创建NSArray的mutableCopy并将其设置为新的NSMutableArray?
  2. Rather than worry about the order of the items (and hence the selected row number); 而不是担心项目的顺序(因此选择行号); how about creating a copy of the object that is selected, and after creating your new NSMutableArray as in step 1, find the matching object in the new array and set that as the selected row in the table using its new index. 如何创建所选对象的副本,并在步骤1中创建新的NSMutableArray之后,在新数组中找到匹配的对象,并使用其新索引将其设置为表中的选定行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM