Обрезка строки внутри цикла в Swift 5

Я использую Swift 5 для разработки на стороне сервера (Kitura), и, поскольку механизм шаблонов не имеет возможности обрезать длинный текст (подумайте о теле сообщения в блоге), мне было интересно, как обрезать его непосредственно в Swift. Другие вопросы решают его по-другому (просто строка не из цикла), поэтому вот мой код:

router.get("/admin", handler: {
 request , response,next  in

    let documents = try collection.find()
    var pages: [[String: String]] = []

    for d in documents {
        print(d)
        pages.append(["title": d.title, "slug": d.slug, "body": d.body, "date": d.date])


 // I would like to trim the value of d.body

        print(d)
    }
    // check if an error occurred while iterating the cursor
    if let error = documents.error {
        throw error
    }
    try response.render("mongopages.stencil", with: ["Pages": pages])
    response.status(.OK)
})

return router
}()

как обрезать значение d.body, чтобы обрезать его до первых 50 символов?


person devnull    schedule 07.12.2020    source источник
comment
Возможно, вам нужно быть немного более точным в отношении того, что вы подразумеваете под «обрезкой». Ограничить до определенной длины? Вырезать по границам слов? Ограничить количество слов? Вы хотите добавить что-нибудь, чтобы показать, что оно было обрезано? и т.д.   -  person flanker    schedule 07.12.2020
comment
@flanker мой плохой: я имею в виду ограничение на 10 слов или 50 символов. Добавлю... после обрезки :)   -  person devnull    schedule 07.12.2020


Ответы (1)


Вы можете расширить String, чтобы предоставить вам эту функциональность (или извлечь ее).

extension String {
    func truncate(to limit: Int, ellipsis: Bool = true) -> String {
        if count > limit {
            let truncated = String(prefix(limit)).trimmingCharacters(in: .whitespacesAndNewlines)
            return ellipsis ? truncated + "\u{2026}" : truncated
        } else {
            return self
        }
    }
}

let default = "Coming up with this sentence was the hardest part of this.".truncate(to: 50)
print(default) // Coming up with this sentence was the hardest part…

let modified = "Coming up with this sentence was the hardest part of this.".truncate(to: 50, ellipsis: false)
print(modified) // Coming up with this sentence was the hardest part

И в вашем случае использования:

router.get("/admin", handler: { (request, response, next)  in
    let documents = try collection.find()
    var pages: [[String: String]] = []
    
    for d in documents {
        let truncatedBody = d.body.truncate(to: 50)
        pages.append(["title": d.title, "slug": d.slug, "body": truncatedBody, "date": d.date])
    }
    
    ...
})
person liquid    schedule 07.12.2020
comment
Это вырезало бы любое слово посередине, так что оно могло бы закончиться так… - person Leo Dabus; 08.12.2020
comment
@LeoDabus Я на самом деле предпочитаю, чтобы это было так, но я вижу, что другие могут этого не делать. Есть ли что-нибудь в Swift, чтобы легко реализовать это, или OP должен будет найти первое пространство перед лимитом вручную? - person liquid; 08.12.2020
comment
это очень интересно. Итак, Swift не имеет способа по умолчанию разрезать или обрезать строку без расширения String? - person devnull; 08.12.2020
comment
@devnull в UIKit UILabel не строка developer.apple.com/documentation/uikit /uilabel/ режим разрыва строки - person Leo Dabus; 08.12.2020
comment
@devnull вам не нужно использовать расширение (но это удобно), и в Swift есть встроенная нарезка строк (я использовал ее в своем расширении), но для пользовательской реализации, подобной этой, в настоящее время ничего нет на полке. - person liquid; 08.12.2020
comment
@bsod stackoverflow.com/a/37536996/2303865 - person Leo Dabus; 08.12.2020