Как реализовать хеши Perl в target-c? - PullRequest
3 голосов
/ 26 апреля 2011

Я просматривал множество сайтов и учебников, а также документацию Apple, и до сих пор не нашел решения: мне кажется, что NSArray, NSDictionary и их изменяемые аналоги совсем не похожи на простые функциональные возможности Perl хэш. Надеюсь, я ошибаюсь, конечно.

Что мне нужно: изменяемая структура динамические ключи и значения (1 ключ - 1 значение, как просто)! Я имею в виду, что я заранее не знаю ключей, и мне нужно легко проверить, существует ли ключ и, если он существует, получить значение или обновить его, если он не существует, ввести новый ключ с новым значением. И мне нужно, чтобы значения были с плавающей точкой , а не объекты или массивы. После того, как я закончил заполнять структуру, мне нужно иметь возможность получить ключи и, наконец, пройтись по значениям по ключам, которые я получил.

Все это легко выполняется в Perl с помощью следующего:

    my %expenses;

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

[...]

Есть ли кто-нибудь, кто мог бы сказать мне, как реализовать нечто подобное в target-c без использования примитивных типов?

Большое спасибо за любую помощь. Фабрицио

Ответы [ 2 ]

4 голосов
/ 26 апреля 2011

Классы коллекций Cocoa и Core Foundation обычно ориентированы на хранение объектов, а не на примитивные значения;обычное решение такой проблемы, как ваша, - это обернуть поплавки в объекты NSNumber.И, к сожалению, синтаксис для получения и установки объектов является более многословным, чем Perl

Кроме этого, 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 голос
/ 26 апреля 2011

Это работает:

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