mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2026-03-18 20:02:25 +00:00
Fix removeEmpty()
This commit is contained in:
@@ -1,33 +1,38 @@
|
||||
import Foundation
|
||||
|
||||
private protocol EmptyRemovable {
|
||||
func removeEmpty() -> Self
|
||||
var isEmpty: Bool { get }
|
||||
}
|
||||
|
||||
extension Array: EmptyRemovable {
|
||||
public func removeEmpty() -> Array {
|
||||
return compactMap {
|
||||
if let e = ($0 as? EmptyRemovable)?.removeEmpty() {
|
||||
return e.isEmpty ? nil : e as? Element
|
||||
}
|
||||
return $0
|
||||
private func convertEmptyToNil<T>(_ value: T) -> T? {
|
||||
switch value as Any {
|
||||
case Optional<Any>.none:
|
||||
return nil
|
||||
case let arr as Array<Any>:
|
||||
let arr = arr.removeEmpty()
|
||||
if !arr.isEmpty,
|
||||
let arr = arr as? T {
|
||||
return arr
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Dictionary: EmptyRemovable {
|
||||
// this is a little trick that defines the generics parameter from optional Value to unwrapped Value
|
||||
private static func removeEmpty<Key, Value>(dict: Dictionary<Key, Value?>) -> Dictionary<Key, Value> {
|
||||
return dict.compactMapValues {
|
||||
if let e = ($0 as? EmptyRemovable)?.removeEmpty() {
|
||||
return e.isEmpty ? nil : e as? Value
|
||||
}
|
||||
return $0
|
||||
case let dict as Dictionary<AnyHashable, Any>:
|
||||
let dict = dict.removeEmpty()
|
||||
if !dict.isEmpty,
|
||||
let dict = dict as? T {
|
||||
return dict
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public func removeEmpty() -> Dictionary<Key, Value> {
|
||||
return Dictionary.removeEmpty(dict: self)
|
||||
default:
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
extension Array {
|
||||
public func removeEmpty() -> Self {
|
||||
compactMap(convertEmptyToNil)
|
||||
}
|
||||
}
|
||||
|
||||
extension Dictionary {
|
||||
public func removeEmpty() -> Self {
|
||||
compactMapValues(convertEmptyToNil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,14 +86,43 @@ class SpecGeneratorTests: XCTestCase {
|
||||
}
|
||||
|
||||
func testRemoveEmpty() {
|
||||
let arr = [[], [1, [2], []], [3]]
|
||||
let removed = arr.removeEmpty()
|
||||
XCTAssertEqual(removed.count, 2)
|
||||
describe {
|
||||
$0.it("removes empty arrays from array") {
|
||||
let arr = [[], [1], [], [2, 3]]
|
||||
XCTAssertEqual(arr.removeEmpty(), [[1], [2, 3]])
|
||||
}
|
||||
|
||||
let dict: [String: Any?] = ["e": nil]
|
||||
let removed2: [String: Any?] = dict.removeEmpty()
|
||||
XCTAssertEqual(removed2.count, 0)
|
||||
let removed3: [String: Any] = dict.compactMapValues { $0 }
|
||||
XCTAssertEqual(removed3.count, 0)
|
||||
$0.it("removes nils from array") {
|
||||
let arr = [nil, 1, nil, 2, 3]
|
||||
XCTAssertEqual(arr.removeEmpty(), [1, 2, 3])
|
||||
}
|
||||
|
||||
$0.it("removes nils and empty arrays from array") {
|
||||
let arr = [nil, [1], nil, [2], []]
|
||||
XCTAssertEqual(arr.removeEmpty(), [[1], [2]])
|
||||
}
|
||||
|
||||
$0.it("removes nils and empty arrays from nested array") {
|
||||
let arr: [[[Int?]?]] = [[[1, nil], nil, []]]
|
||||
XCTAssertEqual(arr.removeEmpty(), [[[1]]])
|
||||
}
|
||||
|
||||
$0.it("removes empty dictionaries from array") {
|
||||
let dict = [["foo": 1], [:], ["bar": 2]]
|
||||
XCTAssertEqual(dict.removeEmpty(), [["foo": 1], ["bar": 2]])
|
||||
}
|
||||
|
||||
$0.it("removes nils from dictionary") {
|
||||
let dict = ["foo": nil, "bar": 1]
|
||||
let b = dict.removeEmpty()
|
||||
XCTAssertEqual(b, ["bar": 1])
|
||||
}
|
||||
|
||||
$0.it("removes empty dictionaries from dictionary") {
|
||||
let dict = ["foo": [:], "bar": ["x": 1]]
|
||||
let b = dict.removeEmpty()
|
||||
XCTAssertEqual(b, ["bar": ["x": 1]])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user