我有这段代码用于将数组中的元素放入UITableView中的相应部分,具体取决于它们的起始字母:
//For each product in the appDelgates products
for (Product *product in appDelegate.m_Products){
if ([product.category isEqualToString:productType]){
//firstLetter is equal to the first letter of the products name
NSString * l_FirstLetter = [product.name substringToIndex:1];
//convert firstString to uppercase
l_FirstLetter = [l_FirstLetter uppercaseString];
//Check what letter firstString is equal to in the alphabet
//Place in appropriate section
//If none, place in "Other" category
if ([l_FirstLetter isEqualToString:@"A"]) {
[[m_AlphabetDictionary objectAtIndex:0] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"B"]) {
[[m_AlphabetDictionary objectAtIndex:1] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"C"]) {
[[m_AlphabetDictionary objectAtIndex:2] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"D"]) {
[[m_AlphabetDictionary objectAtIndex:3] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"E"]) {
[[m_AlphabetDictionary objectAtIndex:4] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"F"]) {
[[m_AlphabetDictionary objectAtIndex:5] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"G"]) {
[[m_AlphabetDictionary objectAtIndex:6] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"H"]) {
[[m_AlphabetDictionary objectAtIndex:7] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"I"]) {
[[m_AlphabetDictionary objectAtIndex:8] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"J"]) {
[[m_AlphabetDictionary objectAtIndex:9] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"K"]) {
[[m_AlphabetDictionary objectAtIndex:10] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"L"]) {
[[m_AlphabetDictionary objectAtIndex:11] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"M"]) {
[[m_AlphabetDictionary objectAtIndex:12] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"N"]) {
[[m_AlphabetDictionary objectAtIndex:13] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"O"]) {
[[m_AlphabetDictionary objectAtIndex:14] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"P"]) {
[[m_AlphabetDictionary objectAtIndex:15] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"Q"]) {
[[m_AlphabetDictionary objectAtIndex:16] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"R"]) {
[[m_AlphabetDictionary objectAtIndex:17] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"S"]) {
[[m_AlphabetDictionary objectAtIndex:18] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"T"]) {
[[m_AlphabetDictionary objectAtIndex:19] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"U"]) {
[[m_AlphabetDictionary objectAtIndex:20] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"V"]) {
[[m_AlphabetDictionary objectAtIndex:21] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"W"]) {
[[m_AlphabetDictionary objectAtIndex:22] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"X"]) {
[[m_AlphabetDictionary objectAtIndex:23] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"Y"]) {
[[m_AlphabetDictionary objectAtIndex:24] addObject:product];
}
else if ([l_FirstLetter isEqualToString:@"Z"]) {
[[m_AlphabetDictionary objectAtIndex:25] addObject:product];
}
else {
[[m_AlphabetDictionary objectAtIndex:26] addObject:product];
}
}
}
有更好的方法吗?
谢谢,
杰克
答案 0 :(得分:3)
将char转换为int减去“A”
的char的int并使用[[m_AlphabetDictionary objectAtIndex:myInt] addObject:product];
并确保,您只使用字母。如果你想支持小写和大写字母,你必须从小写字母中减去'a'的字符。
如果您将来需要支持区域设置和变音符号,那么有更复杂的方法,但这适用于OP中定义的a ... z和A ... Z集:
首先,罗嗦版本记录了它的工作原理:
static inline NSUInteger InsertionIndexForProductNamed(NSString * product) {
assert(0 < product.length && "invalid argument");
const int A = 'A';
const int Z = 'Z';
const int a = 'a';
const int z = 'z';
const unichar first = [product characterAtIndex:0];
const bool isLowercaseAZ = a <= first && z >= first;
const int uppercase = isLowercaseAZ ? (first + A - a) : first;
const bool isUppercaseAZ = A <= uppercase && Z >= uppercase;
if (isUppercaseAZ) {
const int result = uppercase - A;
return (NSUInteger)result;
}
else {
/* not A-Z. place in 'other' */
return 26;
}
}
现在是简短的版本,它更像你在野外看到的那些:
static inline NSUInteger InsertionIndexForProductNamed(NSString* product) {
assert(0 < product.length && "invalid argument");
const unichar first = [product characterAtIndex:0];
switch (first) {
case 'A'...'Z' :
return first - 'A';
case 'a'...'z' :
return first - 'a';
default :
return 26;
}
}
使用中:
/* For each product in the appDelgates products */
for (Product * product in appDelegate.m_Products) {
if ([product.category isEqualToString:productType]) {
const NSUInteger idx = InsertionIndexForProductNamed(product.name);
[[m_AlphabetDictionary objectAtIndex:idx] addObject:product];
}
}
最后,简短的在线实施可以采用以下形式:
/* For each product in the appDelgates products */
for (Product * product in appDelegate.m_Products) {
if ([product.category isEqualToString:productType]) {
const NSUInteger insertionIndex;
const unichar first = [product characterAtIndex:0];
switch (first) {
case 'A'...'Z' :
insertionIndex = first - 'A';
break;
case 'a'...'z' :
insertionIndex = first - 'a';
break;
default :
insertionIndex = 26; // 26 is the index of the 'other' category
break;
}
[[m_AlphabetDictionary objectAtIndex:insertionIndex] addObject:product];
}
}
还请注意我的ObjC/Block-style answer
答案 1 :(得分:1)
与字符混淆让你得到奇怪的问题,你在[0,25]之外的标记处添加对象,这是一个很大的禁忌。通过明确声明您的词典,您可以确保避免使用它。
bool added = NO;
NSArray* theAlphabet = [NSArray arrayWithObjects:@"A",@"B",@"C" ... ,@"Z",nil];
for(int i=0; i<26; i++){
if ([l_FirstLetter isEqualToString:[theAlphabet objectAtIndex:i]]) {
[[m_AlphabetDictionary objectAtIndex:i] addObject:product];
added = YES;
}
}
if(!added)
[[m_AlphabetDictionary objectAtIndex:26] addObject:product];
added
标志确保第一个字母不是字母的对象被添加到数组26中。
答案 2 :(得分:0)
详细说明vikingosegundo的答案:
for (Product *product in appDelegate.m_Products) {
if ([product.category isEqualToString: productType]) {
NSString* l_FirstLetter = [product.name substringToIndex: 1];
l_FirstLetter = [l_FirstLetter uppercaseString];
NSInteger key = l_FirstLetter - 'A';
[[m_AlphabetDictionary objectAtIndex: key] addObject: product];
}
}
这是因为Objective-C允许您从NSString中减去char('A'
)。您可能必须先将l_FirstLetter
转换为char。
答案 3 :(得分:0)
C提供了测试不同类别字符的标准函数,因此我们可以将代码缩短为:
//For each product in the appDelgates products
for (Product *product in appDelegate.m_Products)
{
if ([product.category isEqualToString:productType])
{
//firstLetter is equal to the first letter of the products name in uppercase
int l_FirstLetter = toupper([product.name characterAtIndex:1]);
//Place in appropriate section, if none, place in "Other" category
unsigned index = isupper(l_FirstLetter) ? (l_FirstLetter - 'A') : 26;
[[m_AlphabetDictionary objectAtIndex:index] addObject:product];
}
}
答案 4 :(得分:0)
在我的另一个C-style answer旁边(再次感谢@Justin),我想假设另一个答案。
这次我只使用objective-c语法和块。
创建一个单词数组:
NSString *text = @"Lorem ipsum dolor sit amet,..."; // Lorem ipsum with non-letter words
NSArray *words = [[[text stringByReplacingOccurrencesOfString:@"." withString:@""]
stringByReplacingOccurrencesOfString:@"," withString:@""]
componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
创建并填写字典:
NSMutableDictionary *wordDict = [NSMutableDictionary dictionary];
[words performBlock:^(id element) {
NSString *firstLetter = [[element substringToIndex:1] uppercaseString];
if ([firstLetter isGreaterThanOrEqualTo:@"A"] && [firstLetter isLessThanOrEqualTo:@"Z"]){
if (![[wordDict allKeys] containsObject:firstLetter]) {
NSMutableArray *array = [NSMutableArray array];
wordDict[firstLetter] = array;
}
[wordDict[firstLetter] addObject:element];
} else {
if (![[wordDict allKeys] containsObject:@"other"]) {
NSMutableArray *array = [NSMutableArray array];
wordDict[@"other"] = array;
}
[wordDict[@"other"] addObject:element];
}
}];
NSLog(@"%@",wordDict);
请注意,此代码在NSArray performBlock:
上使用类别方法。此方法只是将块应用于数组中的每个元素。 It can be found at github
-(void)performBlock:(void (^)(id))block
{
for(id element in self) {
block(element);
}
}
输出
{
A = (
amet,
aliquyam,
At,
accusam,
amet,
amet,
aliquyam,
At,
accusam,
amet,
amet,
aliquyam,
At,
accusam,
amet
);
C = (
consetetur,
clita,
consetetur,
clita,
consetetur,
clita
);
//…
L = (
Lorem,
labore,
Lorem,
Lorem,
labore,
Lorem,
Lorem,
labore,
Lorem
);
//…
T = (
tempor,
takimata,
tempor,
takimata,
tempor,
takimata
);
U = (
ut,
ut,
ut
);
V = (
voluptua,
vero,
voluptua,
vero,
voluptua,
vero
);
other = (
"%$",
"!",
"9)7/",
1234,
56hfr
);
}