我正在比较两个单词中包含的字符。在寻求完成此任务时,Set(又名NSSet)似乎是完成此任务的方法。我发现它在比赛中返回假阳性,因此我尝试使用CountedSet(又名NSCountedSet)。

我可以初始化Set没有问题,但是我无法使CountedSet初始化程序起作用。这是我所做的...

我从String开始:

// Let's say myTextField.text = "test"
let textFieldCharacters = myTextField.text?.characters
// word is a string from the ENABLE list of words
let wordCharacters = word.characters


然后我将字符转储到Array中:

var wordCharactersArray = [Character]()
for character in wordCharacters {
    wordCharacterArray.append(character)
}


var textFieldCharactersArray = [Character]()
for character in textFieldCharacters {
    wordCharacterArray.append(character)
}


然后,我从字符数组创建一个Set

let textFieldSet = Set<Character>(textFieldCharactersArray)
let wordSet = Set<Character>(wordCharactersArray)


最后,我测试一下textFieldSet是否是具有以下内容的wordSet的超集:

textFieldSet.isSuperset(of: wordSet)


回到我的示例,如果myTextField.text是“ test”,我将返回word的值,该字符的字符是wordSet的超集,但单个元素的计数与的字符计数不匹配。 myTextField.text

在研究我的问题时,我发现了CountedSet(fka NSCountedSet),我认为这可以解决我的问题。它具有两个方法签名:

public convenience init(array: [AnyObject])
public convenience init(set: Set<NSObject>)


我试过初始化两组字符,如下所示:

let textFieldSet = CountedSet(array: textFieldCharacterArray)
let wordSet = CountedSet(array: wordCharacterArray)


我得到以下错误集


  无法将类型“ [字符]”的值转换为预期的参数类型
  '[AnyObject]'。


所以我尝试像这样初始化集合:

let textFieldSet = CountedSet(array: textFieldCharacterArray as! [AnyObject])


产生以下错误:


  “ AnyObject”不是“字符”的子类型


我还尝试根据方法签名用CountedSet初始化Set,但是当我尝试这样做时也会遇到错误。

如何初始化CountedSet的任何建议将不胜感激。

最佳答案

您是正确的,如果您不仅需要比较元素的存在,还需要比较它们的数量,则应该使用CountedSet,这是对swift 3.0的NSCountedSet重命名。您遇到的问题是CountedSet只能接受属于对象的元素,而Characters不能接受。正如Eric D在其评论中指出的那样,解决此问题的简便方法是将您的[Character]映射到[String],这将桥接到[NSString]

您没有使用Set遇到此问题,因为它是使用任何类型的元素初始化的本机Swift集合类型。这就是为什么您可以使用Set初始化[Character]的原因。

要查看区别:

let word = "helo"
let wordCharacters = Array(word.characters)
let wordSet = Set(wordCharacters)
let wordCharStrings = wordCharacters.map{String($0)}
let wordCountedSet = CountedSet(array: wordCharStrings)

let textField = "hello"
let textFieldCharacters = Array(textField.characters)
let textSet = Set(textFieldCharacters)
let textFieldCharStrings = textFieldCharacters.map{String($0)}
let textFieldCountedSet = CountedSet(array: textFieldCharStrings)

textFieldCountedSet.isSubset(of: wordCountedSet as! Set<NSObject>) // returns false, but if word had two or more l's it would return true
textSet.isSubset(of: wordSet) // returns true

10-08 15:40