有没有一种方法可以结合switch和contains?

12

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

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 case(即使这会稍微改变逻辑),特别是在使用枚举时,switch 语句是一个更好的选择,以避免错误。

如果无法使用 switch 语句实现此目的,我也会感激任何优雅的替代方法。


1
这并不是对你具体问题的回答,但我会定义一个FileExtension类型,它有一个fileType属性,对应着文件类型,例如https://gist.github.com/hamishknight/c211c63e321df33d18e9f90c72d4a20f。 - Hamish
@Hamish 我完全同意你的观点。此外,有些扩展可以同时是“音频”和“视频”。 - Sulthan
3个回答

11

我认为你的整个问题在于,你试图维护每种类型的三个独立集合,而不是直接将它们连接到给定的文件类型:

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
}

5

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

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

1
这对您的情况有效。
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,然后使用每个 case 作为条件。


1
是的,这是我能想到使用switch语句来完成它的唯一方法。不过,我更喜欢你的实现方式。 - Scriptable
我从未见过使用true进行切换...这是如何工作的? - aheze
1
@aheze 它只是反转条件,用于存在多个条件时。就像说当情况为真时。 - Scriptable
有道理,很聪明! - aheze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接