【问题标题】:How to determine if each element in an array contains a certain letter by making an array of a wordlist file (swift 2)如何通过制作单词列表文件的数组来确定数组中的每个元素是否包含某个字母(swift 2)
【发布时间】:2016-02-03 00:56:28
【问题描述】:

我对 swift 比较陌生。我正在尝试制作一个程序,该程序采用单词列表(以字符串数组的形式)并删除不包含用户选择的字母的字符串。所以,如果词表是 ["apple", "banana", "cherry", "date", "endive"] 并且用户选择了字母 "a" (这是变量 "centerletter"), "apple", "banana" 和 "date" 将被返回,因为它们确实包含字母 a。当输入的数组(wordlist)是标准数组,如 ["apple", "banana"] 时,此代码有效。但是,我对这段代码的实际用途是对英语中的每个单词进行排序,如我的文件“words.txt”(我的 swift 项目中的文件之一)中所示。

我已将 words.txt 中的每个单词(由 /n 分隔)分配给 wordlist,如下所示(这是函数):

func arrayFromContentsOfFileWithName(fileName: String) -> [String]? {

    let path = NSBundle.mainBundle().pathForResource("words", ofType: "txt")

    var fileContents: String? = nil
    do {
        fileContents = try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding)
        return fileContents!.componentsSeparatedByString("\n")
    } catch _ as NSError {
        return nil
    }
}

我将 wordlist 分配给 arrayFromContentsOfFileWithName("words.txt") 的结果,如下所示:

var wordlist = arrayFromContentsOfFileWithName("words.txt")

然后我使用此代码处理单词列表(尝试取出单词列表中不包含用户选择的字母(在我的示例中为“a”)的每个单词。此代码适用于标准数组,例如 ["apple", "banana"],但不在使用函数 arrayFromContentsOfFileWithName 制作的数组上。

let centerlet:Character = Character(Array(arrayLiteral: centerletter.text!)[0])

// centerlet 是用户选择的字母。

    for var i = 0; i < wordlist?.count; i++ {
        if wordlist![i].characters.contains(centerlet) {
            print("I am leaving in \(wordlist![i]) because it contains the center letter")
        } else {
            print("I removed \(wordlist![i]) because it did not have the center letter.")
            wordlist?.removeAtIndex(i)
            }
        }

如何将 words.txt 中的所有单词转换为标准的 swift 数组,以便删除所述数组中不包含特定字母的每个单词?谢谢。

【问题讨论】:

  • 我什至尝试将if wordlist![i].characters.contains(centerlet) { 行更改为更可选的if ((wordlist?[i].characters.contains(centerlet)) != nil) {。然后它留在每个单词中,即使它不包含用户选择的字母。
  • 我尝试替换 .characters.contains = .containsString,但没有成功。这基本上是一样的(.characters.contains = .containsString,因为我正在搜索 1 个字符的字符串)。我试过了,还是不行;要么全部否定,要么全部肯定,这取决于我做出 if 语句的可选性(请参阅我的第一条评论)。
  • 删除了之前的评论,因为我想到了同样的事情 :) 这似乎是 Swift 的函数式方法使用 .filter.map 通过返回结果将一个数组转换为另一个数组的完美案例从一个闭包中......这基本上是我在输入这个时 Mundi 在下面写的......
  • 向后遍历单词数组:i = ...count-1; i &gt;= 0; i--
  • 建议编辑问题以发布文本文件,或者 wordList 和 centerLetter 的来源。

标签: ios arrays swift swift2


【解决方案1】:

在使用索引遍历列表时,您正在删除列表中的项目。在枚举列表的同时修改列表通常会导致灾难,并且通常会带来意想不到的结果。

一个简单的过滤器怎么样?

let filteredList = wordlist.filter { !$0.characters.contains(letter) }

【讨论】:

  • 我该如何使用它?仅使用您给出的结果会导致不正确的结果,并在我的代码中用 filterList 替换 wordlist 会产生与最初相同的结果。
  • var filteredList = wordlist!.filter { $0.characters.contains(centerlet) == false } 什么都没过滤
  • Mundi 的解决方案非常完美,而且非常类似于 Swift。 (已投票。)这应该是公认的答案。此代码将创建一个新数组,filteredList,其中包含 wordList 中不包含字母的项目
  • 啊!我看到这里发生了什么!我的数组不是正确的类型(你说得对,这适用于标准数组!)。现在,我正在从文件中的文本创建一个数组,每个元素用换行符分隔。也许这个数组格式错误?
  • @mc01 没有它是什么意思?没有那个“!”我得到一个错误。但这个结果听起来不错(用 a 返回三个单词)。是的,它删除了数组的每个元素并返回一个空数组。我不知道为什么!
【解决方案2】:

不遵循Character(Array(arrayLiteral: centerletter.text!)[0])的语法

centerletter.text! 来自哪里?据我所知,您正在从单个字母创建一个单元素数组,然后将该字母元素作为字符从数组中拉出。为什么?

以下只是使用centerlet = "a",它工作正常...

var wordList = ["apple", "banana", "cherry", "date", "endive"]

let centerlet:Character = "a"

for var i = 0; i < wordList.count; i++ {
    if wordList[i].characters.contains(centerlet) {
        print("I am leaving in \(wordList[i]) because it contains the center letter")
    } else {
        print("I removed \(wordList[i]) because it did not have the center letter.")
        wordList.removeAtIndex(i)
    }
}
//results 
I am leaving in apple because it contains the center letter
I am leaving in banana because it contains the center letter
I removed cherry because it did not have the center letter.
I removed endive because it did not have the center letter.

【讨论】:

  • 啊!我看到这里发生了什么!我的数组不是正确的类型(你说得对,这适用于标准数组!)。现在,我正在从文件中的文本创建一个数组,每个元素用换行符分隔。也许这个数组格式错误?
  • 这太疯狂了。 Swift 的 filter 命令非常适合这个。请参阅 Mundi 的回答。
  • 实际上,Duncan,这行得通,只是不适用于我的确切情况(感谢 mc01,您帮助我发现了我的问题)。请在上面查看我的问题的更新:)。
  • @mc01 是的(我的错),所以知道如何解决我的新问题吗?请查看我的更新以提出问题。
  • 此代码将无法正常工作,因为您正在从数组中删除项目并弄乱数组索引。 (它似乎可以工作,但你会跳过评估一些单词。)这段代码的另一个问题是 Swift 3.0 将删除 C 风格的 for (;;) 循环,所以这段代码注定要失败。如果要索引数组,则必须向后索引,以免在删除单词时弄乱尚未评估的单词的数组索引。但是使用过滤器。真的。
猜你喜欢
  • 1970-01-01
  • 2014-11-01
  • 2012-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多