matsuda
7/12/2016 - 2:24 AM

NSNullを除去する

NSNullを除去する

//
//  UnwrappedNSNull.swift
//  WeddingApps
//
//  Created by Kosuke Matsuda on 2016/06/24.
//  Copyright © 2016年 Appirits Inc. All rights reserved.
//

import Foundation

///
/// MARK: - UnwrappedNSNullable
///
protocol UnwrappedNSNullable {
    func reduceNSNull() -> Self
}


///
/// MARK: - extensions
///
extension Optional: UnwrappedNSNullable {
    func reduceNSNull() -> Optional<Wrapped> {
        switch self {
        case .Some(let value):
            if let g = unwrappedNSNull(value) {
                return .Some(g)
            }
            return self
        default:
            return self
        }
    }
}

extension Array: UnwrappedNSNullable {
    func reduceNSNull() -> [Element] {
        return reduce([Element]()) { (result, element) in
            var result = result
            if let value = unwrappedNSNull(element) {
                result.append(value)
            }
            return result
        }
    }
}

extension Dictionary: UnwrappedNSNullable {
    func reduceNSNull() -> [Key: Value] {
        return reduce([Key: Value]()) { (result, element) in
            var result = result
            if let value = unwrappedNSNull(element.1) {
                result[element.0] = value
            }
            return result
        }
    }
}

extension Set: UnwrappedNSNullable {
    func reduceNSNull() -> Set<Element> {
        return reduce(Set<Element>()) { (result, element) in
            var result = result
            if let value = unwrappedNSNull(element) {
                result.insert(value)
            }
            return result
        }
    }
}


///
/// MARK: - functions
///
public func unwrappedNSNull<T>(value: T?) -> T? {
    guard let v = value else {
        return value.reduceNSNull()
    }
    if v is NSNull {
        return nil
    }
    if let r = v as? UnwrappedNSNullable {
        return r.reduceNSNull() as? T
    }
    if let r = v as? NSArray {
        return (r as Array).reduceNSNull() as? T
    }
    if let r = v as? NSDictionary {
        return (r as Dictionary).reduceNSNull() as? T
    }
    if let r = v as? NSSet {
        return (r as Set).reduceNSNull() as? T
    }
    return v
}