#objective-c #nsarray #nsdictionary
#objective-c #nsarray #nsdictionary
Вопрос:
Я просмотрел множество сайтов и руководств, а также документацию Apple, и до сих пор не нашел решения: мне кажется, что NSArray, NSDictionary и их изменяемые аналоги совсем не похожи на простые функциональные возможности хэша Perl. Я надеюсь, что я, конечно, ошибаюсь.
Что мне нужно: изменяемая структура из динамических ключей и значений (1 ключ — 1 значение, вот так просто)! Я имею в виду, я не знаю ключей заранее, и мне нужно легко проверить, существует ли ключ, и если он существует, получить значение или обновить его, если оно не существует, введите новый ключ с новым значением. И мне нужно, чтобы значения были числами с плавающей точкой, а не объектами или массивами. После того, как я закончил заполнять структуру, мне нужно иметь возможность извлекать ключи и, наконец, перебирать значения по полученным ключам.
Все это легко достигается в Perl с помощью следующего:
my %expenses;
if (exists $expenses{$key}) {
$expenses{$key} = $amount;
} else {
$expenses{$key} = $amount;
}
[...]
Есть ли кто-нибудь, кто мог бы сказать мне, как реализовать нечто подобное в objective-c без использования примитивных типов?
Большое вам спасибо за любую помощь. Fabrizio
Комментарии:
1. Почему вы не можете использовать
NSMutableDictionary
? Ваш код будет не таким коротким, как версия Perl, но я верю, что он может сделать все, что вам нужно. К сожалению, это также заставит вас обернуть ваши значения с плавающей точкой вNSNumber
.2. Я думал, что не смогу это использовать, я думал, что попробовал правильный путь, но я ошибался, как показали мне два других плаката здесь… Я рад, что был неправ 🙂 Спасибо.
Ответ №1:
Классы Cocoa и Core Foundation collection обычно ориентированы на хранение объектов, а не примитивных значений; обычное решение проблемы, подобной вашей, заключается в том, чтобы обернуть значения с плавающей точкой в объекты 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. Вам нужно добавить какой-то
[NSMutableDictionary dictionary]
код для создания экземпляра расходов.2. Спасибо, Аноми, твой ответ указывал в правильном направлении, рыжик еще больше упростил свой код, но вы оба мне очень помогли. Спасибо!
3. @carrot-top: Да. Я указал на это в примечательном комментарии.
4. Я указывал на потенциальную выгоду новичка в Obj-C. Я уверен, что вы прекрасно это знали. 🙂
Ответ №2:
Это работает:
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);
Комментарии:
1. Ну, рыжик, какой лучший комментарий я могу здесь поместить, чем строки из моей консоли отладки? Операции… Я не могу поместить столько символов, но это работает гладко! Большое вам спасибо, я застрял с созданием NSArray из NSDictionaries и не смог найти простого способа. Большое вам спасибо!!!
2. Ах … забыл задать два вопроса: 1) что означает amount / 2? 2) Мой ключ на самом деле представляет собой комбинацию из трех ключей, могу ли я использовать их и выполнять поиск по любой их комбинации? Я имею в виду key1 и key2, key1 и key2 и key3, только key3 и т.д. …?
3.
amount/2
Было просто случайным числом для запуска первой части предложения if.