不知道类型的Swift变量比较

时间:2015-10-01 11:49:26

标签: swift

所以我现在对Swift很新,正在上课(如下所示)。

变量selectedOption可以是StringInt的数组,并且这些方法需要比较接收到的数组值。

以下代码有效,但我不喜欢这样的事实:我正在键入检查并复制代码以比较字符串然后再次比较方法isSelectedremoveSelectedItem

    if selectedOption is String {
        return (self.selectedOption!.indexOf({ $0 as! String == selectedOption as! String }) != nil)
    } else if ( selectedOption is Int ) {
        return (self.selectedOption!.indexOf({ $0 as! Int == selectedOption as! Int })) != nil
    }

必须有更好的方法吗?

public class SearchOption {

    private var title: String
    private var allowAny: Bool
    private var allowMultiple: Bool
    private var dependencies: [SearchOption]?

    // Store the selected Item in an array of AnyObjects.
    private var selectedOption: [AnyObject]?

    init(title: String, allowAny: Bool, allowMultiple: Bool, dependencies: [SearchOption]?) {
        self.title = title
        self.allowAny = allowAny
        self.allowMultiple = allowMultiple
        self.dependencies = dependencies
    }

    public func setSelectedItem(selectedOption: AnyObject) -> Void {
        if self.selectedOption == nil || !self.allowMultiple{
            self.selectedOption = [AnyObject]()
        }
        self.selectedOption?.append(selectedOption)
    }

    public func getSelectedItem() -> [AnyObject]? {
        return self.selectedOption
    }

    public func removeSelectedItem(selectedOption: AnyObject) -> Void {
        if self.selectedOption != nil {
            if selectedOption is String {
                self.selectedOption = self.selectedOption!.filter() { $0 as! String != selectedOption as! String }
            } else if ( selectedOption is Int ) {
                self.selectedOption = self.selectedOption!.filter() { $0 as! Int != selectedOption as! Int }
            }
        }
    }

    public func isSelected(selectedOption: AnyObject) -> Bool {
        if self.selectedOption != nil {
            if selectedOption is String {
                return (self.selectedOption!.indexOf({ $0 as! String == selectedOption as! String }) != nil)
            } else if ( selectedOption is Int ) {
                return (self.selectedOption!.indexOf({ $0 as! Int == selectedOption as! Int })) != nil
            }
        }
        return false
    }

    public func clearSelectedItems() -> Void {
        self.selectedOption = nil
    }

    public func checkDependencies() -> Bool {
        if dependencies != nil {
            for dependency in dependencies! {
                if dependency.getSelectedItem() == nil {
                    return false
                }
            }
        }
        return true
    }

}

var make: SearchOption = SearchOption(title: "Make", allowAny: true, allowMultiple: true, dependencies: nil)
make.setSelectedItem("Vauxhall")
make.setSelectedItem("Mazda")
make.setSelectedItem("Audi")
print(make.getSelectedItem())
make.removeSelectedItem("Mazda")
print(make.getSelectedItem())
print(make.isSelected("Audi"))

输出:

Optional([Vauxhall, Mazda, Audi])
Optional([Vauxhall, Audi])
true

2 个答案:

答案 0 :(得分:2)

扩展对问题的评论:你应该做 类泛型,以便它可以与StringInt一起使用 项目。您需要的是可以将项目与==进行比较, 即类型为Equatable

类声明将是

public class SearchOption<T : Equatable> {
   // ...
}

并且AnyObject的所有出现都必须由T替换。

isSelected方法简化为

public func isSelected(selectedOption: T) -> Bool {
    if self.selectedOption != nil {
        return self.selectedOption!.contains( { $0 == selectedOption })
    }
    return false
}

可以使用可选链接进一步简化 和 nil-coalescing operator ??

public func isSelected(selectedOption: T) -> Bool {
    return self.selectedOption?.contains( { $0 == selectedOption }) ?? false
}

类似地:

public func removeSelectedItem(selectedOption: T) -> Void {
    self.selectedOption = self.selectedOption?.filter( { $0 != selectedOption } )
}

对于String项,您将创建该类的实例 与

let make = SearchOption<String>(title: "Make", allowAny: true, allowMultiple: true, dependencies: nil)

答案 1 :(得分:1)

使用Generics和Equatable进行管理以解决问题(我之前从未真正使用过这些问题,原谅我)

在课堂上,T被约束为一种Equatable,似乎让.filter().indexOf感到高兴。

创建实例时,您将传递您将使用的类型:

var make: SearchOption = SearchOption<String>(title: "Make", allowAny: true, allowMultiple: true, dependencies: nil)

结果类如下所示

public class SearchOption<T: Equatable> {

    private var title: String
    private var allowAny: Bool
    private var allowMultiple: Bool
    private var dependencies: [SearchOption]?

    // Store the selected Item in an array of AnyObjects.
    private var selectedOption: [T]?

    init(title: String, allowAny: Bool, allowMultiple: Bool, dependencies: [SearchOption]?) {
        self.title = title
        self.allowAny = allowAny
        self.allowMultiple = allowMultiple
        self.dependencies = dependencies
    }

    public func setSelectedItem(selectedOption: T) -> Void {
        if self.selectedOption == nil || !self.allowMultiple {
            self.selectedOption = [T]()
        }
        self.selectedOption?.append(selectedOption)
    }

    public func getSelectedItem() -> [T]? {
        return self.selectedOption
    }

    public func removeSelectedItem(selectedOption: T) -> Void {
        if self.selectedOption != nil {
            self.selectedOption = self.selectedOption!.filter() { $0 != selectedOption }
        }
    }

    public func isSelected(selectedOption: T) -> Bool {
        if self.selectedOption != nil {
            return (self.selectedOption!.indexOf({ $0 == selectedOption }) != nil)
        }
        return false
    }

    public func clearSelectedItems() -> Void {
        self.selectedOption = nil
    }

    public func checkDependencies() -> Bool {
        if dependencies != nil {
            for dependency in dependencies! {
                if dependency.getSelectedItem() == nil {
                    return false
                }
            }
        }
        return true
    }

}

var make: SearchOption = SearchOption<String>(title: "Make", allowAny: true, allowMultiple: true, dependencies: nil)
make.setSelectedItem("Vauxhall")
make.setSelectedItem("Mazda")
make.setSelectedItem("Audi")
print(make.getSelectedItem())
make.removeSelectedItem("Audi")
print(make.getSelectedItem())
print(make.isSelected("Mazda"))