如何在Swift中使用可选变量拆分多行字符串文字

时间:2018-01-01 05:49:05

标签: arrays swift macos cocoa swift4

我正在尝试获取与某个全局变量匹配的某个类中包含的元素的索引。使用CSS查询搜索节点会给我一个包含潜在匹配元素的列表,但是 - 正如Kanna’s documentation指出的那样 - 这样的查询返回XPathObjects作为数组。我可以看到从列表中获取索引值的唯一方法是将它从数组转换为字符串,然后可以用新行分割;但是,我似乎无法获取列表以获取字符串值。典型编译会话日志的相关部分如下:

Kazuo®/Ishiguro® Auprès® (2 pack)
Orange
Kazuo®/Ishiguro® Auprès® Folio Toujours (2 Pack)
Blue
…

我尝试了this thread中一张海报建议的三种方法来连接上面的输出:

1)。 componentsSeparatedByCharactersInSet

for node in (doc?.css("a[class^='product-link']"))! {
    let multiLineString = node.text!
    let newlineChars = NSCharacterSet.newlineCharacterSet()
    let lineArray = multiLineString.componentsSeparatedByCharactersInSet(newlineChars).filter{!  $0.isEmpty}
}   

理想情况下,这会打印[Kazuo®/Ishiguro® Auprès® (2 pack), Orange, Kazuo®/Ishiguro® Auprès® Folio Toujours (2 Pack), Blue];它会引发错误。点击fix会导致另一个错误 - 另一个错误。

2)。分割

for node in (doc?.css("a[class^='product-link']"))! { 
    let multiLineString = node.text!
    let newlineChars = NSCharacterSet.newlineCharacterSet()
    let lineArray = multiLineString.utf16.split { newlineChars.characterIsMember($0) }.flatMap(String.init)
}

产生与componentsSeparatedByCharactersInSet相同的结果:Cannot call value of non-function type 'CharacterSet' - > fix - >错误 - > fix - >错误。

3)。 enumerateLines

for node in (doc?.css("a[class^='product-link']"))! {             
    let multiLineString = node.text!
    var lineArray = [String]()
    multiLineString.enumerateLines { (line, stop) -> () in
        lineArray.append(line)
    }
}

此解决方案实际构建,但它将每个列表项返回为function()

当我在Playgrounds中对简单的多行字符串文字进行尝试时,这些方法有效,但由于某种原因,它们不能处理上面的输出。解决此问题的最简单方法是使用func index(of element: Element) -> Int?,但这样做会给我Cannot convert value of type 'String' to expected argument type 'Character'错误。我是Swift的新手,所以如果有更多经验的人可以提出解决这个问题的替代方法,我会非常感谢你的帮助!

3 个答案:

答案 0 :(得分:1)

关于你更大的目标,这就是你应该如何解决问题:

var prodIndex = 0
var testProd = "Prod" // to be replaced by user input

for node in (doc?.css("a[class^='name-link']"))! {
    let words = testProd.split(separator: " ")
    if prodIndex % 2 == 0 {
        if node.text! == testProd {
            print("FOUND: " + testProd)
        }

        prodIndex += 1
    }
}

答案 1 :(得分:0)

代码已过时。 Swift 3+中的第一种方法是

let newlineChars = CharacterSet.newlines
let lineArray = multiLineString.components(separatedBy: newlineChars).filter{ !$0.isEmpty }

要将文字放在一行中,请使用

let oneLine = multiLineString.components(separatedBy: newlineChars).filter{ !$0.isEmpty }.joined(separator: " ")

答案 2 :(得分:0)

我想你想说你想要

Kazuo®/Ishiguro® Auprès® (2 pack)
Orange
Kazuo®/Ishiguro® Auprès® Folio Toujours (2 Pack)
Blue

作为单行字符串是否正确?

for node in (doc?.css("a[class^='product-link']"))! {
    // suggestion: use a guard here, it's good practice to safely unwrap optionals
    guard let multiLineString = node.text else { return }

    let lineArray = multiLineString.components(separatedBy: .newlines).joined(separator: " ")
 }

打印:Kazuo®/Ishiguro® Auprès® (2 pack) Orange Kazuo®/Ishiguro® Auprès® Folio Toujours (2 Pack) Blue