【问题标题】:Swift Error Cannot convert value of type '[String.Element]' (aka 'Array<Character>') to expected argument type '[String]'Swift 错误无法将类型“[String.Element]”(又名“Array<Character>”)的值转换为预期的参数类型“[String]”
【发布时间】:2018-10-02 10:04:53
【问题描述】:

我正在尝试使用以下 Swift 代码从给定单词创建一个字母数组(我有一个用于 allWords 的单词数组,但为简单起见,我现在只是在其中添加了一个示例单词):

let allWords = ["Leopards"]
var arrayOfLetters = Array(allWords[0])

let everyPossibleArrangementOfLetters = permute(list: arrayOfLetters)

func permute(list: [String], minStringLen: Int = 3) -> Set<String> {
    func permute(fromList: [String], toList: [String], minStringLen: Int, set: inout Set<String>) {
        if toList.count >= minStringLen {
            set.insert(toList.joined(separator: ""))
        }
        if !fromList.isEmpty {
            for (index, item) in fromList.enumerated() {
                var newFrom = fromList
                newFrom.remove(at: index)
                permute(fromList: newFrom, toList: toList + [item], minStringLen: minStringLen, set: &set)
            }
        }
    }

    var set = Set<String>()
    permute(fromList: list, toList:[], minStringLen: minStringLen, set: &set)
    return set
}

我从:Calculate all permutations of a string in Swift获得此代码

但出现以下错误: 无法将类型“[String.Element]”(又名“Array”)的值转换为预期的参数类型“[String]”

我尝试了以下方法,它有效,但每个单词需要超过 10 秒(取决于重复字母的数量),我希望找到更好的解决方案。

var arrayOfLetters: [String] = []

     for letter in allWords[0] {
     arrayOfLetters.append(String(letter))
     }

     let everyPossibleArrangementOfLetters = permute(list: arrayOfLetters)

我无法让以下解决方案正常工作,尽管我认为我承诺我无法通过数组中项目的 productID 名称,而我的数组项目没有命名...... Migration from swift 3 to swift 4 - Cannot convert String to expected String.Element

我还在创建另一个数组并检查每个单词以确保它们的有效性,我遇到了同样的错误,我以同样的方式纠正了 array.append,这在那个位置增加了更多的时间好吧。

var everyPossibleArrangementOfLettersPartDeux: [String] = []
     for word in everyPossibleArrangementOfLetters {
     everyPossibleArrangementOfLettersPartDeux.append(word)
     }

numberOfRealWords = possibleAnagrams(wordArray: everyPossibleArrangementOfLettersPartDeux)

func possibleAnagrams(wordArray: [String]) -> Int {

    func isReal(word: String) -> Bool {
        let checker = UITextChecker()
        let range = NSMakeRange(0, word.utf16.count)
        let misspelledRange = checker.rangeOfMisspelledWord(in: word, range: range, startingAt: 0, wrap: false, language: "en")

        return misspelledRange.location == NSNotFound
    }

    var count = 0

    for word in wordArray {
        if isReal(word: word) {
            count += 1
            //print(word)
        }

        }
        return count
        }

我希望对 array.append 的相同替换在这两个地方都可以工作。

【问题讨论】:

  • 要解决此错误,请注意,如果您尝试将 [myArray] 传递到您打算传递 myArray 的位置,则会出现此错误。改正那个错字,你就成功了!

标签: arrays swift


【解决方案1】:

此行返回一个 Character 数组,而不是 String 一个:

var arrayOfLetters = Array(allWords[0])

您可以将其转换为 String 数组,如下所示:

var arrayOfLetters = Array(allWords[0]).map{String($0)}

你也可以这样写:

var arrayOfLetters = allWords[0].characters.map{String($0)}

【讨论】:

    【解决方案2】:

    问题是Array(allWords[0]) 产生[Character] 而不是您需要的[String]

    您可以在String 上调用map(这是Characters 的集合,并在每个字符上使用String.init 将其转换为String)。 map 的结果将是 [String]

    var arrayOfLetters = allWords[0].map(String.init)
    

    注意事项:

    1. 当我在 Playground 中尝试此操作时,我收到了神秘消息 Fatal error: Only BidirectionalCollections can be advanced by a negative amount。这似乎是 Playground 问题,因为它可以在应用中正常运行。
    2. 只是单词 "Leopards" 产生 109,536 排列。

    另一种方法

    解决问题的另一种方法是认识到permute 不必在[String] 上工作。它可以改用[Character]。另外,既然您总是以String 开头,为什么不将该字符串传递给外部permute 并让它为您创建[Character]

    最后,由于逻辑上认为您可能只需要原始单词的字谜,因此将 minStringLen 设为可选值,并设置为 nil,如果未指定该值,则只需使用 word.count

    func permute(word: String, minStringLen: Int? = nil) -> Set<String> {
        func permute(fromList: [Character], toList: [Character], minStringLen: Int, set: inout Set<String>) {
            if toList.count >= minStringLen {
                set.insert(String(toList))
            }
            if !fromList.isEmpty {
                for (index, item) in fromList.enumerated() {
                    var newFrom = fromList
                    newFrom.remove(at: index)
                    permute(fromList: newFrom, toList: toList + [item], minStringLen: minStringLen, set: &set)
                }
            }
        }
    
        var set = Set<String>()
        permute(fromList: Array(word), toList:[], minStringLen: minStringLen ?? word.count, set: &set)
        return set
    }
    

    例子:

    print(permute(word: "foo", minStringLen: 1))
    
    ["of", "foo", "f", "fo", "o", "oof", "oo", "ofo"]
    
    print(permute(word: "foo"))
    
    ["foo", "oof", "ofo"]
    

    【讨论】:

    • 这是最聪明的方法,虽然我承认我觉得它很容易忘记,因为我从来没有真正理解这样写表达式的逻辑。这在很大程度上是一个侧面,但我的观点是[String]("Leopard")[String]("Leopard".characters) 会更有意义,并且与[Int](1...3) 等更一致,但如果有人可以帮助我了解这一点,我会很高兴。
    • String 再次是Character 的集合,因此在String 上调用map 将对每个Character 进行操作。使用每个 Character 调用 String.init 会将其转换为 String
    • 问题是类型转换。 [String]("Leopard") 不起作用,因为这不是 Array&lt;String&gt; 的初始化程序,它采用 StringArray&lt;Character&gt;。每个Character 都需要转换为String,这无法通过强制转换来完成。您必须在每个 Character 上调用 String 初始化程序。
    • 感谢您花时间澄清。
    • 我已经在一个单独的问题中解决了这个神秘的错误。见Fatal error: Only BidirectionalCollections can be advanced by a negative amount
    【解决方案3】:

    如果是可选字符或字符串

    usedLetters.append(currentWord.randomElement().map(String.init)!)
    

    这里 usedLetters 是 Array[String] currentWord 是可选字符串

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多