2016-12-19 2 views
1

У меня есть строка, которая является сочетание первого и LastName:Маскировка Имя и фамилия Строка с *

Джонни Tuck

Я хочу, чтобы скрыть эту строку, как, что в Swift 3:

J ***** T ***

Как я могу это сделать?

+3

Пожалуйста, покажите, что вы пробовали. – shallowThought

+3

Что делать, если есть среднее имя (которое может быть сокращено или нет)? Как насчет иностранных языков, таких как китайский? –

+0

@shallowThought трудно показать что-то, если вы не знаете, с чего начать. @ mTuran это крутой вопрос :) – Fluidity

ответ

8

Вы можете, например. использовать сопоставление с образцом для строчных символов и заменить те, которые соответствуют шаблону с звездочками символов (*):

let name = "Johnny Tuck" 
let pattern = Character("a")..."z" 
let maskedName = String(name.characters.map { pattern ~= $0 ? Character("*") : $0 }) 
print(maskedName) // J***** T*** 

Если цель не заменить строчные символы на * а маскировать все символы, которые не являются первое из данного слова (например, для конкретного разделителя " "), вы можете отделить имя String от разделителя и применить маскировку ко всем, кроме начального символа для всех разделенных слов (подзаголовков), в конце концов реконструировать замаскированную строку:

import Foundation 
let name = "johnny lucky tuck" 
let maskedName = name.components(separatedBy: " ") 
    .filter { !$0.isEmpty }.map { $0.characters } 
    .map { String($0.first!).uppercased() + String(repeating: "*", count: $0.dropFirst(1).count) } 
    .joined(separator: " ") 
print(maskedName) // J***** L**** T*** 

Обратите внимание на приведенный выше uppercased(), который устанавливает начальную незамаскированную букву в верхнюю часть (даже если она не изначально). Если вы не желаете этого верхнего кода, просто удалите вызов .uppercased() выше.

+0

хорошая демонстрация карты. – Fluidity

+2

Если первый символ - маленькая буква, это не будет работать правильно, не так ли? –

+1

не будет работать с диакритикой. – Sulthan

3

очень простое решение:

(разделение на слова, отфильтровать пустые слова, индекс каждый символ в слове, карты к звездам, снова присоединиться к полному имени)

let fullname = "This Is My Name" 

let result = fullname 
    .components(separatedBy: CharacterSet.whitespaces) 
    .filter { !$0.isEmpty } 
    .map { (name: String) in 
     let mappedCharacters = name.characters.enumerated().map { (index, letter) in 
      return (index == 0) ? letter : "*" 
     } 

     return String(mappedCharacters) 
    } 
    .joined(separator: " ") 

print("Result:", result) // Result: T*** I* M* N*** 
1

Если ваше намерение заменить каждый символ, кроме первого в каждом слове звездой, то это будет быть другим возможным решением:

extension String { 
    /// Replace all characters except the first by a star. 
    func starredWord() -> String { 
     return String(characters.prefix(1) + characters.dropFirst().map { _ in "*" }) 
    } 

    /// Star every "word" in a string. 
    func starred() -> String { 
     var result = "" 
     self.enumerateSubstrings(in: startIndex..<endIndex, options: .byWords) { 
      (s, range, enclosingRange, _) in 
      result += 
       // Append the substring preceeding the word ... 
       self[enclosingRange.lowerBound..<range.lowerBound] 
       // ... the starred word ... 
       + (s?.starredWord() ?? "") 
       // ... and the substring following the word. 
       + self[range.upperBound..<enclosingRange.upperBound] 
     } 
     return result 
    } 
} 

Здесь enumerateSubstrings используется с опцией .byWords для для определения слов в текущей локали, даже если они ограничены символами пунктуации .

Пример:

let name = "John M. Doe, sen." 
print(name.starred()) 
// J*** M. D**, s**. 
Смежные вопросы