有没有办法结合开关和包含?

时间:2018-05-10 10:31:36

标签: swift if-statement switch-statement contains

我们假设我有三个包含扩展名的集合:

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
}

现在我想要做的是实现一个函数,该函数根据传递给它的字符串返回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 :(得分:11)

我认为你的整个问题是你试图为每种类型维护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
}

答案 1 :(得分:3)

您可以向模式匹配运算符~=添加重载:

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

答案 2 :(得分:0)

这适合你的情况

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,然后在有多个条件时将每个案例用作条件。