【问题标题】:iOS comparing NSDictionary valuesiOS 比较 NSDictionary 值
【发布时间】:2015-12-28 01:40:45
【问题描述】:

我正在获取两个JSONs 并将它们分别存储为NSArrayNSDictionary

这就是JSON 数据结构的样子

(
        {
            Cells = (
                {
                    ValueName = "name";
                    Text = "John Appleseed";
                },
                {
                    "Option": {
                        "Text": "19"
                    },
                    ValueName = "age"
                }, etc...
            )
        },
        {
           Cells = (
                {
                    ValueName = "name";
                    Text = "John Appleseed";
                },
                {
                    ValueName = "age",
                    "Option": {
                        "Text": "19"
                    }
                }, etc...
            )
        }
)

{
    "map": {
        "first": "name",
        "second": "age"
    }, etc...
}   

两者具有需要交叉引用的值(因为一个包含所有数据 (allData),另一个包含所需数据的“映射”(mapData))。

如何将allData 的所有值与mapData 的所有值进行比较,同时尽可能记住简单性和记忆力?

一个很好的方法是使用containsObject 匹配[allData allValues][mapData allValues],并返回一个NSArray 和匹配的object。唉,事实并非如此。该方法完美地说明了我希望实现的目标。

我最初的方法很慢,占用内存且丑陋(凭记忆写的):

NSArray *allData = [NSJSONSerialization JSONObjectWithData:allDataJSON options:kNilOptions error:&JSONSerializationError];
NSDictionary *mapData = [NSJSONSerialization JSONObjectWithData:mapDataJSON options:kNilOptions error:&JSONSerializationError];
NSMutableDictionary *resultData = [[NSMutableDictionary alloc] init];

for (int count = 0; count<allData.count; count++) {
    id dataValue = [allData objectAtIndex:count];
    for (id key in mapData) {
        if ([[mapData objectForKey:key] containsObject:dataValue]) {
            [resultData setObject:[dataValue objectForKey:@"value"] forKey:key]
        }
    }
}

能够引用匹配值的每个匹配项也很重要(正如我的方法中所做的那样)。


这不是基于意见的问题,因为优化和内存使用不是意见。

【问题讨论】:

  • 除了原始 JSON 结果和resultData 您的方法不分配任何对象。那么,您想如何减少这种情况呢?降低内存使用的唯一方法是以 SAX 样式反序列化 allData JSON 并立即删除不匹配的项目。
  • 示例数据有助于理解用例。

标签: ios objective-c json compare nsarray


【解决方案1】:

我发现使用此数据模型内存效率高且速度非常快(allData 的长度为 1000 行,平均时间为 0.001 秒)。


通过从mapData 中提取所有想要的值并将它们放在NSArray 中,这些值可以很容易地与allData 的值匹配。

通过mapDataArray 循环时,可以创建一个辅助循环以通过allData 的值。如果mapDataArray containsObject 返回true,则数据可以存储在瞬时存储字典中。

这样可以轻松管理需要哪些数据以及可以忽略哪些数据。在第一个循环内创建瞬时存储非常重要(稍后您会看到)。

如果找到mapDataArray 中的所有值(通过检查mapDataArray.countmomentaryData.count)我们可以break 当前循环(从而节省时间和内存)。

只看代码可能更容易理解真正发生的事情。


问题中引用的数据对象。

NSArray *allData = [NSJSONSerialization JSONObjectWithData:allDataJSON options:kNilOptions error:&JSONSerializationError];
NSDictionary *mapData = [NSJSONSerialization JSONObjectWithData:mapDataJSON options:kNilOptions error:&JSONSerializationError];

‏ 创建mapDataArray,循环遍历它,创建瞬时字典,附加找到的对象并将瞬时数据附加到resultData

NSArray *mapDataArray = [[NSArray alloc] init];

mapDataArray = [[mapDataArray arrayByAddingObjectsFromArray:[[mapData objectForKey:@"map"] objectForKey:@"first"]] arrayByAddingObjectsFromArray:[[mapData objectForKey:@"map"] objectForKey:@"second"]];
mapDataArray = [[NSOrderedSet orderedSetWithArray:mapDataArray] array]; //Remove duplicates

NSMutableDictionary *resultData = [[NSMutableDictionary alloc] init];
for (int count = 0; count<allData.count; count++) {
    NSMutableDictionary *momentaryData = [[NSMutableDictionary alloc] init];
    int dataNumber = count;

    NSArray *literal = [[allData objectAtIndex:dataNumber] objectForKey:@"Cells"];
    for (int count = 0; count<literal.count; count++) {
        id literal = [[[allData objectAtIndex:dataNumber] objectForKey:@"Cells"] objectAtIndex:count];

        if ([mapDataArray containsObject:[literal objectForKey:@"ValueName"]]) {
            id value = [literal objectForKey:@"Text"];

            if (!value) {
                value = [literal objectForKey:@"Option"];
                if (value && ![value isEqual:[NSNull null]]) {
                    value = [value objectForKey:@"Text"];
                } else {
                    value = @"";
                }
            }

            [momentaryData setObject:[NSString stringWithFormat:@"%@", value] forKey:[literal objectForKey:@"ValueName"]];

            if (mapDataArray.count == momentaryData.count) {
                break; //We have what we came for...
            }
        }
    }

    [resultData setObject:momentaryData forKey:[NSString stringWithFormat:@"%d", dataNumber]];
}

【讨论】:

    【解决方案2】:

    您可以使用isEqual: 比较arraysdictionaries

    对于arrays,它比较arrays 是否具有相同数量的元素或匹配的元素是否相等。

    对于dictionaries,它会检查两者是否具有相同数量的键、一组键是否相等以及一个dictionary 中的每个键是否与另一个dictionary 中的匹配键具有相同的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-05
      • 1970-01-01
      • 2018-01-25
      • 1970-01-01
      相关资源
      最近更新 更多