如何在objective-c中实现Perl哈希?

时间:2022-09-02 10:45:53

I have been looking through many sites and tutorials, and the Apple documentation, and still haven't found a solution: it seems to me that NSArray, NSDictionary and their mutable counterparts are not at all resembling the simple functionalities of a Perl hash. I hope I am wrong of course.

我一直在浏览许多网站和教程,以及Apple文档,但仍未找到解决方案:在我看来,NSArray,NSDictionary及其可变对应物完全不像Perl哈希的简单功能。我希望我当然错了。

What I need: a mutable structure of dynamic keys and values (1 key - 1 value, as simple as that)! I mean, I don't know keys in advance and I need to easily check whether a key exists and if it exists retrieve a value or update it, if it does not exist enter the new key with the new value. And I need the values to be floats, not objects nor arrays. After I finished populating the structure I need to be able to retrieve the keys and finally looping through the values by the keys I retrieved.

我需要的是:动态键和值的可变结构(1键 - 1值,就这么简单)!我的意思是,我不提前知道密钥,我需要轻松检查密钥是否存在,是否存在检索值或更新它,如果不存在,请输入带有新值的新密钥。我需要值是浮点数,而不是对象和数组。在我完成填充结构后,我需要能够检索键,最后通过我检索的键循环遍历值。

All of this is easily accomplished in Perl with the following:

所有这些都可以通过以下方式在Perl中轻松完成:

    my %expenses;

    if (exists $expenses{$key}) {
       $expenses{$key} += $amount;
    } else {
       $expenses{$key} = $amount;
    }

[...]

Is there someone who could tell me how to implement something similar in objective-c without using primitive types?

是否有人可以告诉我如何在不使用原始类型的情况下在objective-c中实现类似的东西?

Thank you so much for any help. Fabrizio

非常感谢你的帮助。法布里奇奥

2 个解决方案

#1


1  

This works:

这有效:

NSString *key=@"fish";
NSMutableDictionary *expenses = [NSMutableDictionary dictionary];
float amount=22.0;

[expenses setObject:[NSNumber numberWithFloat:amount/2] forKey:key];

if ([expenses objectForKey:key]) {
    [expenses setObject:
         [NSNumber numberWithFloat:
             [[expenses objectForKey:key] floatValue] + amount] forKey:key];
} else {
    [expenses setObject:[NSNumber numberWithFloat:amount] forKey:key];
}

NSLog(@"expenses: %@",expenses);

#2


4  

The Cocoa and Core Foundation collection classes are generally oriented towards storing objects rather than primitive values; the usual solution to a problem like yours is to wrap the floats in NSNumber objects. And unfortunately, the syntax for getting and setting the objects is more verbose than Perl's

Cocoa和Core Foundation集合类通常面向存储对象而不是原始值;像你这样的问题的通常解决方案是将浮动包装在NSNumber对象中。不幸的是,获取和设置对象的语法比Perl更加冗长

Other than that, an NSMutableDictionary should do exactly what you want. The keys can be any string, or any other object that can be copied (i.e. it conforms to the NSCopying protocol), you can get a list of all keys, and you can check if a key "exists" in the dictionary by simply trying to fetch the corresponding value. The code corresponding to your example could look something like this:

除此之外,NSMutableDictionary应该完全符合您的要求。键可以是任何字符串,或任何其他可以复制的对象(即它符合NSCopying协议),您可以获取所有键的列表,并且您可以通过简单地尝试检查字典中是否存在键“存在”获取相应的值。与您的示例对应的代码可能如下所示:

// NB: there no autovivification in Objective-C. Be sure to initialize this somewhere
// before using it!
NSMutableDictionary *expenses;

if ([expenses objectForKey:key]) {
    // This *could* be done in one statement. But it would be very long, so I split
    // it in two for clarity.
    float currentValue = [[expenses objectForKey:key] floatValue];
    [expenses setObject:[NSNumber numberWithFloat:currentValue + amount] forKey:key];
} else {
    [expenses setObject:[NSNumber numberWithFloat:amount] forKey:key];
}

#1


1  

This works:

这有效:

NSString *key=@"fish";
NSMutableDictionary *expenses = [NSMutableDictionary dictionary];
float amount=22.0;

[expenses setObject:[NSNumber numberWithFloat:amount/2] forKey:key];

if ([expenses objectForKey:key]) {
    [expenses setObject:
         [NSNumber numberWithFloat:
             [[expenses objectForKey:key] floatValue] + amount] forKey:key];
} else {
    [expenses setObject:[NSNumber numberWithFloat:amount] forKey:key];
}

NSLog(@"expenses: %@",expenses);

#2


4  

The Cocoa and Core Foundation collection classes are generally oriented towards storing objects rather than primitive values; the usual solution to a problem like yours is to wrap the floats in NSNumber objects. And unfortunately, the syntax for getting and setting the objects is more verbose than Perl's

Cocoa和Core Foundation集合类通常面向存储对象而不是原始值;像你这样的问题的通常解决方案是将浮动包装在NSNumber对象中。不幸的是,获取和设置对象的语法比Perl更加冗长

Other than that, an NSMutableDictionary should do exactly what you want. The keys can be any string, or any other object that can be copied (i.e. it conforms to the NSCopying protocol), you can get a list of all keys, and you can check if a key "exists" in the dictionary by simply trying to fetch the corresponding value. The code corresponding to your example could look something like this:

除此之外,NSMutableDictionary应该完全符合您的要求。键可以是任何字符串,或任何其他可以复制的对象(即它符合NSCopying协议),您可以获取所有键的列表,并且您可以通过简单地尝试检查字典中是否存在键“存在”获取相应的值。与您的示例对应的代码可能如下所示:

// NB: there no autovivification in Objective-C. Be sure to initialize this somewhere
// before using it!
NSMutableDictionary *expenses;

if ([expenses objectForKey:key]) {
    // This *could* be done in one statement. But it would be very long, so I split
    // it in two for clarity.
    float currentValue = [[expenses objectForKey:key] floatValue];
    [expenses setObject:[NSNumber numberWithFloat:currentValue + amount] forKey:key];
} else {
    [expenses setObject:[NSNumber numberWithFloat:amount] forKey:key];
}