简体   繁体   中英

How can I split a multi-line string literal with optional variables in Swift

I'm trying to get the index of an element contained in a certain class that matches a global variable. Searching for nodes with CSS queries gives me a list with potential matching elements, but — as Kanna's documentation points out — such queries return XPathObjects that act as arrays. The only way I can see to get index values from said list is to convert it from an array into a string, which can then be split by new lines; however, I can't seem to get the list to take a string value. The relevant part of a typical compile session log follows:

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

I've tried three methods suggested by one poster in this thread to concatenate the above output:

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}
}   

Ideally, this would print [Kazuo®/Ishiguro® Auprès® (2 pack), Orange, Kazuo®/Ishiguro® Auprès® Folio Toujours (2 Pack), Blue] ; it raises an error instead. Clicking fix leads to another error — and another one.

2). split

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)
}

Yields the same result as componentsSeparatedByCharactersInSet : Cannot call value of non-function type 'CharacterSet' -> fix -> error -> fix -> error.

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)
    }
}

This solution actually builds, but it returns each list item as function() .

These methods work when I try them on simple multi-line string literals in Playgrounds, but for some reason they don't work on the output above. The easiest way to solve this problem would be to use func index(of element: Element) -> Int? , but doing so gives me a Cannot convert value of type 'String' to expected argument type 'Character' error. I'm new to Swift, so if anyone with more experience could suggest alternative approaches to this problem, I would much appreciate the help!

Regarding your larger goal, this is how you should go about solving the problem:

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
    }
}

The code is outdated. The first method in Swift 3+ is

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

To put the text in one line use

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

I think you are trying to say you want

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

as a single line string correct?

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: " ")
 }

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM