开发者

How to implement Perl hashes in objective-c?

开发者 https://www.devze.com 2023-02-28 12:10 出处:网络
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

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 function开发者_Go百科alities of a Perl hash. I hope I am wrong of course.

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.

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

    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?

Thank you so much for any help. Fabrizio


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

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:

// 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];
}


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);
0

精彩评论

暂无评论...
验证码 换一张
取 消