【问题标题】:Objective-C, making an NSArray of each unique character in an NSStringObjective-C,为 NSString 中的每个唯一字符创建一个 NSArray
【发布时间】:2014-02-10 20:44:31
【问题描述】:

我四处搜索,发现几个问题的答案与这个问题相似,但并不完全相同,我无法获得这些答案中给出的示例代码来为我工作。我承认这很可能是我对 Objective-C 的无知造成的。我的情况是这样的:

我有一个来自包含各种字符的文本文件的 NSString。字符串的长度可以根据文本文件中的内容而有所不同。我需要创建一个数组,给出字符串中的每个字符。

我已经尝试了 5 种不同的方法来解决这个问题(其中三种来自本网站上的答案),但我为此所做的每一次努力都导致了 a) 我无法追踪的分段错误,b)数组在给出编译器警告时保持 NULL,或 c) 数组在没有编译器警告的情况下保持 NULL。万一这很重要,我正在使用:gcc -framework Foundation -std=c99 TestCode.m -o TestProgram

抱歉,这里没有具体的代码,因为我沮丧地删除了所有失败的努力。我想你不应该在尝试学习编程语言的同时尝试学习你正在应用该语言的新主题是有原因的:)

有人能帮我提供几个sn-ps吗?

【问题讨论】:

  • 为什么要一个数组中的所有字符?您应该显示最接近您的代码并描述它显示的错误。
  • 所以你希望 NSString @"hello" 成为 NSArray @[@"h", @"e", @"l", @"o"],对吗?
  • 为什么不从头开始呢?使用NSSet(单字符字符串)来跟踪您看到的字符,并在完成后将集合转换为数组。
  • 数组应该是每个 -unique- 字符。你说得对,安德烈。
  • 代理对,或者更常见的是分解的 Unicode 字符呢?

标签: objective-c nsstring nsarray


【解决方案1】:

你会这样做。

  1. 将文件内容读入NSSString
  2. 枚举所有字符
  3. 将它们添加到NSMutableSet
  4. 从集合中获取allObjects

在大致翻译成这个的代码中

// 1. Get the contents of the file 
NSError *error = NULL;
NSString *textFromFile = [[NSString alloc] initWithContentsOfFile:pathToFile
                                                         encoding:NSUTF8StringEncoding
                                                            error:&error];
if (!textFromFile) {
    // handle error
}

// 2. Enumerate all the characters
// (I'm enumerating composed characters to be able to support for example Chinese)
NSMutableSet *characters = [NSMutableSet set];
[textFromFile enumerateSubstringsInRange:NSMakeRange(0, textFromFile.length)
                                 options:NSStringEnumerationByComposedCharacterSequences
                              usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                                  // 3. Add them to a mutable set
                                  [characters addObject:substring];
                              }];
// 4. Get all the objects from the set (note that it's not sorted)
NSArray *allCharacters = [characters allObjects];

【讨论】:

  • 也会处理分解的字符!
  • 次要备注(与问题无关):if (error) 应为if (textFromFile == nil)
  • @MartinR 为什么会这样?这是否意味着根本不需要错误变量?
  • @AndreyChernukha:见developer.apple.com/library/mac/documentation/cocoa/conceptual/…重要提示:方法的返回值指示成功或失败。虽然间接返回 Cocoa 错误域中的错误对象的 Cocoa 方法如果通过直接返回 nil 或 NO 指示失败,则保证返回此类对象,但在尝试对NSError 对象。
  • 太棒了!这非常有效。我什至不知道 NSSet 的存在......作为额外的奖励,我正在阅读关于 NSSet 的文档并发现了 NSCountedSet。我在你有一个集合的地方替换了一个计数集合,这解决了我什至还没有开始研究的下一个问题。非常感谢!
【解决方案2】:

这里有一个 NSString 类别,它将把字符串中的所有字符组成一个 NSArray:

- (NSArray*)charactersAsArray
{
    NSMutableArray* array = [@[] mutableCopy];
    for (int i = 0; i < self.length; i++) {
        NSRange composedCharRange = [self rangeOfComposedCharacterSequenceAtIndex:i];
        NSString* character = [self substringWithRange:composedCharRange];
        if (character) {
            [array addObject:character];
        }
    }
    return array;
}

或者你可以使用独特的字符:

- (NSArray*)uniqueCharactersAsArray
{
    NSMutableArray* array = [@[] mutableCopy];
    for (int i = 0; i < self.length; i++) {
        NSRange composedCharRange = [self rangeOfComposedCharacterSequenceAtIndex:i];
        NSString* character = [self substringWithRange:composedCharRange];
        if (character && ![array containsObject:character]) {
            [array addObject:character];
        }
    }
    return array;
}

你可以这样使用它...

NSString* myString = @"disdiefgdsaéYsué8d9ieo";
NSArray* allCharactersArray = [myString charactersAsArray];
NSArray* uniqueCharactersArray = [myString uniqueCharactersAsArray];

【讨论】:

  • OP 想要一个最多包含一个字符的数组,我认为......在您的情况下,您刚刚将字符串分解为单个字符。此外,这种方法可能会破坏组合字符,例如é.
  • 您的代码只需将所有字符添加到数组中。提问者需要一组 UNIQUE 字符
  • 我错过了他要求独特角色的事实。我已经更新了我的答案。
  • 请注意,并非每个字符的长度都为“1”(组合字符)。进一步阅读:Dealing with Emoji,WWDC 2011 会议 128 - 高级文本处理和 WWDC 2012 会议 215 - 文本和语言分析。
  • @dreamlax 我已经编辑了我的答案,现在返回给定索引处组合字符的 NSRange。但是,我想指出的是,在测试此代码时,我发现您作为组合字符示例提供的组合字符将被我的原始实现“分解”,始终返回长度为 1 的 NSRange。无论如何,你会看到我在上面添加的更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
  • 2013-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-22
相关资源
最近更新 更多