Bagaimana saya bisa membagi string literal multi-baris dengan variabel opsional di Swift

Saya mencoba mendapatkan indeks elemen yang terdapat dalam kelas tertentu yang cocok dengan variabel global. Mencari node dengan kueri CSS memberi saya daftar dengan elemen potensial yang cocok, tetapi — sebagai dokumentasi Kanna menunjukkan — kueri seperti itu mengembalikan XPathObjects yang bertindak sebagai array. Satu-satunya cara saya bisa mendapatkan nilai indeks dari daftar tersebut adalah dengan mengubahnya dari array menjadi string, yang kemudian dapat dibagi dengan baris baru; namun, sepertinya saya tidak bisa membuat daftar tersebut mengambil nilai string. Bagian yang relevan dari log sesi kompilasi tipikal adalah sebagai berikut:

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

Saya sudah mencoba tiga metode yang disarankan oleh satu poster di utas ini untuk menggabungkan keluaran di atas:

1). komponenSeparatedByCharactersInSet

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

Idealnya, ini akan mencetak [Kazuo®/Ishiguro® Auprès® (2 pack), Orange, Kazuo®/Ishiguro® Auprès® Folio Toujours (2 Pack), Blue]; itu malah menimbulkan kesalahan. Mengklik fix menyebabkan kesalahan lain — dan kesalahan lainnya.

2). membelah

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

Menghasilkan hasil yang sama seperti 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)
    }
}

Solusi ini sebenarnya dibuat, tetapi mengembalikan setiap item daftar sebagai function().

Metode ini berfungsi ketika saya mencobanya pada literal string multi-baris sederhana di Playgrounds, tetapi karena alasan tertentu metode tersebut tidak berfungsi pada keluaran di atas. Cara termudah untuk mengatasi masalah ini adalah dengan menggunakan func index(of element: Element) -> Int?, tetapi hal itu memberi saya kesalahan Cannot convert value of type 'String' to expected argument type 'Character'. Saya baru mengenal Swift, jadi jika ada orang yang lebih berpengalaman dapat menyarankan pendekatan alternatif untuk masalah ini, saya akan sangat menghargai bantuannya!


person solo    schedule 01.01.2018    source sumber


Jawaban (3)


Mengenai tujuan Anda yang lebih besar, inilah cara Anda harus menyelesaikan masalah:

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
    }
}
person ch1maera    schedule 07.01.2018

Kode ini sudah usang. Metode pertama di Swift 3+ adalah

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

Untuk meletakkan teks dalam satu baris gunakan

let oneLine = multiLineString.components(separatedBy: newlineChars).filter{ !$0.isEmpty }.joined(separator: " ")
person vadian    schedule 01.01.2018
comment
Ini memberi saya: ["Kazuo®/Ishiguro® Auprès® (2 pack)"]\n["Orange"]\n["Kazuo®/Ishiguro® Auprès® Folio Toujours (2 Pack)"]\n["Blue"]. Bagaimana cara menempatkannya di jalur yang sama? Memisahkan berdasarkan baris baru hanya mereplikasi masalah yang ditunjukkan di atas. - person solo; 01.01.2018

Saya pikir Anda mencoba mengatakan Anda ingin

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

sebagai string baris tunggal, benar?

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

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

person mmr118    schedule 01.01.2018
comment
Hmm, entah kenapa saya masih mendapatkan keluaran asli Kazuo®/Ishiguro® Auprès® (2 pack)\nOrange\nKazuo®/Ishiguro® Auprès® Folio Toujours (2 Pack)\nBlue. Mungkinkah ini masalah sistem? - person solo; 01.01.2018
comment
Coba ganti .newlines dengan ”\n” - person mmr118; 01.01.2018
comment
Hmmm, mungkin ada sesuatu yang hilang dari pertanyaan yang tidak jelas karena tidak ada yang jelas mengapa ini harus berhasil. - person mmr118; 01.01.2018
comment
Bagaimana Anda menangani lineArray setelah ditugaskan? - person mmr118; 01.01.2018
comment
Ketika saya menjalankan print(lineArray) itu memberi saya hasil yang sama seperti di atas. - person solo; 01.01.2018
comment
Sebenarnya ini sangat mengganggu saya karena ini tidak berhasil. Jika mau, twitter saya terdaftar di akun tersebut, jika mau, Anda dapat mengirim pesan langsung kepada saya di sana dan kita dapat mencoba pendekatan yang lebih detail mengenai hal ini. - person mmr118; 02.01.2018