Есть ли способ объединить переключатель и содержит? - PullRequest
0 голосов
/ 10 мая 2018

Давайте предположим, что у меня есть три набора, содержащие расширения:

let photos: Set = ["jpg", "png", "tiff"]
let videos: Set = ["mp4", "mov", "mkv"]
let audios: Set = ["mp3", "wav", "wma"]

и простой enum как:

enum FileType {
    case photo, video, audio, unknown
}

Теперь я хочу реализовать функцию, которая возвращает опцию FileType, основываясь на том, какая строка передана ей и какой набор содержит ее:

func getType(of file: String) -> FileType {
    if photos.contains(file) { return .photo }
    if videos.contains(file) { return .video }
    if audios.contains(file) { return .audio }

    return .unknown
}

Это должно работать, как и ожидалось, но мне интересно, есть ли подход для преобразования оператора if в один switch случай (даже если он немного изменится в логику), особенно при работе с перечислениями switch оператор (ы) - лучший выбор, чтобы избежать ошибок.

Если это невозможно сделать с помощью оператора switch, я также буду признателен за любую элегантную альтернативу (ы).

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

Я думаю, что вся ваша проблема заключается в том, что вы пытаетесь поддерживать 3 независимых набора для каждого типа вместо того, чтобы соединять их напрямую с данным типом файла:

enum FileType: String {
    case photo, video, audio, unknown
}

let extensions: [FileType: Set<String>] = [
    .photo: ["jpg", "png", "tiff"],
    .video: ["mp4", "mov", "mkv"],
    .audio: ["mp3", "wav", "wma"]
]

func getType(of file: String) -> FileType {
    return extensions.first { $0.value.contains(file) }?.key ?? .unknown
}
0 голосов
/ 10 мая 2018

Вы можете добавить перегрузку к оператору сопоставления с образцом ~=:

func ~= <T> (pattern: Set<T>, value: T) -> Bool {
    return pattern.contains(value)
}

func getType(of file: String) -> FileType {
    switch file {
    case photos: return .photo
    case videos: return .video
    case audios: return .audio
    default: return .unknown
    }
}
0 голосов
/ 10 мая 2018

Это работает для вашего случая

let photos: Set = ["jpg", "png", "tiff"]
let videos: Set = ["mp4", "mov", "mkv"]
let audios: Set = ["mp3", "wav", "wma"]

enum FileType {
    case photo, video, audio, unknown
}

func getType(of file: String) -> FileType {

   switch true {

   case photos.contains(file):
       return .photo
   case videos.contains(file):
       return .video
   case audios.contains(file):
       return .audio
   default:
       return .unknown
    }
}

print(getType(of: "mp4"))

видео

Вы можете включить true, а затем использовать каждый случай как условный, если у вас есть несколько условий.

...