swift set intersect, union, subtract - swift

Does anyone know how to implement set operations with user defined classes, with its property as operated conditions. For instance:
class myClass {
var figure: Int!
}
let classObj1 = myClass()
classObj1.figure = 1
let classObj2 = myClass()
classObj2.figure = 2
let classObj3 = myClass()
classObj3.figure = 1
let set1: Set = [classObj1]
let set2: Set = [classObj2, classObj3]
Is there any method like: (pseudo code)
set2.substract(set1) {s2, s1 in s2.figure == s1.figure}
...so the expected result is [classObj2]?
Many thanks for any suggestion!

Certainly. Make your MyClass conform to Hashable and Equatable in such a way that == compares the figure values. Example:
class MyClass : Hashable {
var figure: Int
init(f:Int) {figure = f}
var hashValue : Int {return figure}
}
func ==(lhs:MyClass, rhs:MyClass) -> Bool {
return lhs.figure == rhs.figure
}

Related

Extension optional Array with Optional Element. Is it even possible?

I have a protocol FooProtocol. and a class Bar<Foo:FooProtocol>. Inside a class an Array var mess: [Foo?]? to keep [foo1, foo2, nil, foo3...] or nil
And I try to make extension for this array to count new Foo object. I prefer to have protocols, because Foos could be very different objects delivered from outer world.
protocol FooProtocol {
....
init(from heaven: Int)
}
extension Optional where
Wrapped: Collection,
Wrapped.Element == Optional,
Wrapped.Element.Wrapped: FooProtocol // 'Wrapped' is not a member type of 'Wrapped.Element'
{
var united: Wrapped.Element.Wrapped { // Nope
let i = ...
return Wrapped.Element.Wrapped(from: i) // Nope
}
}
class Bar<Foo:FooProtocol> {
var mess: [Foo?]?
init (with mess: [Foo?]?) {
self.mess = mess
}
var important: Foo {
return mess.united
}
}
Any ideas? I'm blocked.
Edit 1:
After Leo suggestions I changed some parts of my code. But still stucked. This time more code from Playgrounds.
Any object that could be converted into '[Double]'. Could be color (as RGBA), Bezier curve, square, whatever...
public protocol FooProtocol {
var atomized: () -> [Double] {get}
static var count: Int {get}
init(_ array:[Double])
init()
}
public extension Array where Element: FooProtocol {
var average: Element {
var resultAtoms: [Double] = []
let inputAtoms = self.map {$0.atomized()}
for i in 0..<Element.count {
let s = inputAtoms.reduce(into: 0.0, {$0 += $1[i]}) / Double (Element.count)
resultAtoms.append(s)
}
return Element(resultAtoms)
}
}
extension Optional where
Wrapped: Collection,
Wrapped.Element == Optional<FooProtocol>
{
typealias Foo = Wrapped.Element.Wrapped // Doesn't work. How to get class?
var average: Foo { // I cannot use Wrapped.Element, it's Optional
if let thatsList = self {
let withOptionals = Array(thatsList) // OK, its [Optional<FooProtocol>]
let withoutOptionals = thatsList.compactMap({$0}) // OK, its [FooProtocol]
// This is funny, called from class works and makes 'bingo'.
return withoutOptionals.average // Error: Value of protocol type 'FooProtocol' cannot conform to 'FooProtocol'; only struct/enum/class types can conform to protocols
} else {
return Foo() // Hello? init Wrapped? Foo? How to get Foo()?
}
}
}
class Bar<Foo:FooProtocol> {
var mess: [Foo?]?
init (with mess: [Foo?]?) {
self.mess = mess
}
func workOn() {
let z:Foo = mess.average // OK, I can make 'mess.average ?? Foo()' but prefer not do it
}
// Thats OK
func workHard() { // To prove 'Array extension where Element: FooProtocol' works
if let messExist = mess {
let withoutOptionals = messExist.compactMap({$0})
let bingo = withoutOptionals.average //It's OK
}
}
}
class SomeFoo : FooProtocol {
static var count = 3
required init() {
a = 0
b = 0
c = 0
}
required init(_ array: [Double]) {
self.a = Int(array[0])
self.b = Float(array[1])
self.c = array[2]
}
var atomized: () -> [Double] {
return {return [Double(self.a), Double(self.b), self.c]}
}
var a: Int
var b: Float
var c: Double
}
let aFoo = SomeFoo([1, 2, 3])
let bFoo = SomeFoo([7, 9, 1])
let cFoo = SomeFoo([2, 6, 5])
let barData = [nil, aFoo, nil, bFoo, cFoo]
let barWithData = Bar(with: barData)
let barWithoutData = Bar<SomeFoo>(with: nil)
Maybe I should forget about extending array and make some functions inside a class (I'm almost sure I will need those functions somewhere else)
Edit 2
Even if I try to simplify and to make extension for Array I found troubles.
extension Array where
Element == Optional<FooProtocol>
{
func averageNils <Foo: FooProtocol>() -> Foo {
let withOptionals = Array(self) // OK, its [Optional<FooProtocol>]
let withoutOptionals = self.compactMap({$0}) // OK, its [FooProtocol]
return withoutOptionals.average as! Foo // Error: Value of protocol type 'FooProtocol' cannot conform to 'FooProtocol'; only struct/enum/class types can conform to protocols
}
}
From my understanding, it should work as you did, but one never knows what happens in the swift compiler world (and especially it's error messages).
Anyway, you can circumvent digging deeper into Wrapped.Element.Wrapped by specifyig the Wrapped.Element more precisely to be an Optional<FooProtocol>:
protocol FooProtocol {}
class Foo : FooProtocol {}
extension Optional where
Wrapped: Collection, //OK
Wrapped.Element == Optional<FooProtocol> // still good
{
var unfied: Wrapped.Element // Should be 'Foo' if self is '[Foo?]?' {
{
return 1 == 0 ? nil : Foo()
}
}

Calculate a hashValue from a func in Swift

I want to send a store a method address in a class, allowing the class to call that method. I want this class to be Hashable, and I want the hashValue to be calculated from the method such that 2 objects pointing to the same method have the same hashValue.
Here is the class init that attempts to calculate the hashValue, but it fails. I think it hashes a pointer to the local variable.
typealias functionAlias = ((Double) -> ())?
class FunctionPointer: Hashable {
private let functionPointer: functionAlias
private let hash: Int
init( functionPointer: functionAlias ) {
self.functionPointer = functionPointer
var f = functionPointer
var h = 0
withUnsafePointer(to: &f, {
ptr in
h = ptr.hashValue
})
self.hash = h
print("self.hash = \(self.hash)")
}
}
Thanks

Read-Only properties

I need help with "read-only" in swift. I tried various ways, but simply couldn't figure out how to compile it without errors. Here's the question and what i thought of.
Create a read-only computed property named isEquilateral that checks to see whether all three sides of a triangle are the same length and returns true if they are and false if they are not.
var isEquilateral: Int {
}
If you want a "read-only" stored property, use private(set):
private(set) var isEquilateral = false
If it is a property calculated from other properties, then, yes, use computed property:
var isEquilateral: Bool {
return a == b && b == c
}
For the sake of completeness, and probably needless to say, if it is a constant, you’d just use let:
let isEquilateral = true
Or
struct Triangle {
let a: Double
let b: Double
let c: Double
let isEquilateral: Bool
init(a: Double, b: Double, c: Double) {
self.a = a
self.b = b
self.c = c
isEquilateral = (a == b) && (b == c)
}
}
Something like this? (as suggested by #vacawama in the comments)
struct Triangle {
let edgeA: Int
let edgeB: Int
let edgeC: Int
var isEquilateral: Bool {
return (edgeA, edgeB) == (edgeB, edgeC)
}
}
Let's test it
let triangle = Triangle(edgeA: 5, edgeB: 5, edgeC: 5)
triangle.isEquilateral // true
or
let triangle = Triangle(edgeA: 2, edgeB: 2, edgeC: 1)
triangle.isEquilateral // false
A read-only property is a property with getter but no setter. It is always used to return a value.
class ClassA {
var one: Int {
return 1
}
var two: Int {
get { return 2 }
}
private(set) var three:Int = 3
init() {
one = 1//Cannot assign to property: 'one' is a get-only property
two = 2//Cannot assign to property: 'two' is a get-only property
three = 3//allowed to write
print(one)//allowed to read
print(two)//allowed to read
print(three)//allowed to read
}
}
class ClassB {
init() {
var a = ClassA()
a.one = 1//Cannot assign to property: 'one' is a get-only property
a.two = 2//Cannot assign to property: 'two' is a get-only property
a.three = 3//Cannot assign to property: 'three' setter is inaccessible
print(a.one)//allowed to read
print(a.two)//allowed to read
print(a.three)//allowed to read
}
}

How to prevent duplicate code when initializing variables?

A class has some variables to be initialized in init() and at the same time, the class provides a function to restore these variables to their initial values in restoreInitValues(). Is there any way I can achieve this without setting these values twice (duplicate code) inside both init() and restoreInitValues()?
class Foo {
var varA: Int
var varB: Int
var varC: Int
init() {
//restoreInitValues() // error: call method before all stored proproties are initalized
//or I have to have duplicate code here as restoreInitValues below
varA = 10
varB = 20
varC = 30
}
func restoreInitValues() {
varA = 10
varB = 20
varC = 30
}
}
Personally I would assign the 3 default values to 3 class scope constants, then use those values to init and restore. You could also eliminate the assigning statements in the init if you want, and assign the value when you declare the var. In addition, by having your defaults defined in a class constant if you need to add any other functions to the class they'll be available for use.
class Foo {
let defaultA = 10
let defaultB = 20
let defaultC = 20
var varA: Int
var varB: Int
var varC: Int
init() {
varA = defaultA
varB = defaultB
varC = defaultC
}
func restoreInitValues() {
varA = defaultA
varB = defaultB
varC = defaultC
}
}
You could also define a struct, use it to assign your values, and then use your reset function to init.
struct values{
static let defaultA = 10
static let defaultB = 20
static let defaultC = 30
}
class test {
var a: Int = 0
var b: Int = 0
var c: Int = 0
init(){
resetValues()
}
func resetValues(){
(a, b, c) = (values.defaultA, values.defaultB, values.defaultC)
}
}
Use implicitly unwrapped optionals.
class Foo {
var varA: Int!
var varB: Int!
var varC: Int!
init() {
restoreInitValues()
}
func restoreInitValues() {
varA = 10
varB = 20
varC = 30
}
}
Update: Code's answer below about Implicitly Unwrapped Optionals is the answer. I'm not sure why I couldn't find it in the docs before. I'm leaving my answer for posterity, but you should accept Code's answer.
being new to swift, I gave it a try and found these two solutions, but I'm not sure if they're the best solutions.
The problem seems to be that swift tries hard to ensure that no class instance will ever have uninitialized properties (unless they're marked as optional) after initialization has been performed. It won't let you call non-static methods because you might use the instance before all properties are set. Also, it doesn't trust you to call another method which initializes all of the properties for you presumably because that would be really hard to verify.
For classes, use a private static method to return default values:
class Foo {
//...
init() {
(varA, varB, varC) = Foo.defaultValues()
}
func restoreInitValues() {
(varA, varB, varC) = Foo.defaultValues()
}
static private func defaultValues() -> ( Int, Int, Int ) {
return (10, 20, 30)
}
}
If you don't need a class, structs are copyable by value:
struct Foo {
//...
mutating func restoreInitValues() {
self = Foo()
}
}
or you could give up on restoreInitValues() and just do this:
var f = Foo()
f.varA = 10000
// instead of resetting the internal state of `f`, just replace it with
// a new `Foo` instance
f = Foo()
or you could use a static private method that modifies Foo instances, but to get around the compiler you have to make your properties be optional. This solution has a definite Ick factor:
class Foo {
var varA: Int?
var varB: Int?
var varC: Int?
init() {
Foo.resetValues(in: self)
}
func restoreInitValues() {
Foo.resetValues(in: self)
}
static private func resetValues(in foo: Foo) {
foo.varA = 10
foo.varB = 20
foo.varC = 30
}
}
This leads us back to the heart of the problem: swift requires that all properties be optional or initialized. Another solution would be to simply give all of the properties values (meaningless or not). The downside is that the property definitions may be misleading to someone reading the code for the first time.
class Foo {
var varA = -1
var varB = -1
var varC = -1
init() {
restoreInitValues()
}
func restoreInitValues() {
varA = 10
varB = 20
varC = 30
}
}
Last, check out the answers to this similar question: How to implement two inits with same content without code duplication

Selecting class depending on variable

I have two classes ClassOne and ClassTwo. I want to initialize a different one depending on a variable value, i want to do something like:
if(a == "0") {
let b = ClassOne();
}else{
let b = ClassTwo();
}
without having to write it everytime I need it. Something like:
let b = MainClass()
and gets called ClassOne() or ClassTwo() depending on the case, a is a global variable.
In order for this to work the two types should be related either by extending a common base class or by implementing the same protocol. Further, subsequent operations on b would be restricted to these the two classes have in common.
If you are fine with that restriction, you can do it like this:
protocol CommonProtocol {
func foo() -> Double
var bar : Int { get }
}
class ClassOne : CommonProtocol {
...
}
class ClassTwo : CommonProtocol {
...
}
func MainClass() -> CommonProtocol {
if(a == "0") {
return ClassOne()
} else {
return ClassTwo()
}
}
...
let b = MainClass()
b.foo()
print(b.bar)
Note: You could forego all of the above in favor of a completely dynamic approach by following matt's advise.
You can do it, but it isn't going to be useful without further effort. Consider the following:
class ClassOne {}
class ClassTwo {}
Now we proceed to initialize a variable as an instance of one of these classes. To do so, we must type the variable as AnyObject:
var which : Bool { return true /* or false */}
let obj : AnyObject
switch which {
case true:
obj = ClassOne()
case false:
obj = ClassTwo()
}
You now have obj as either a ClassOne instance or a ClassTwo instance. But there's a problem. You don't know which it is. The AnyObject typing preserves the real underlying type (polymorphism), but it also hides the type. Every time you use obj, you will have to test whether it is a ClassOne or a ClassTwo and cast it to that type in order to use it.
if obj is ClassOne {
(obj as! ClassOne).doSomethingClassOneKnowsHowToDo()
}
The question is: is the pain worth the gain? I would suggest that your desire to do this in the first place is probably a Bad Smell and you should revise your intended architecture. Strict static typing is the point of Swift; you are wrong to want to throw it away.
You could use the ternary operator to do it quickly, however you do need to do it every time:
let b = (a == 0) ? ClassOne() : ClassTwo() //If a==0 let b = ClassOne if not let b= ClassTwo.
#dasblinkenlight solution is great but you can also do like this
protocol MyProto {
var x: Int { get }
}
class A: MyProto {
var x = 10
var y = 10
}
class B: MyProto {
var x = 20
}
class Demo {
var type: MyProto!
init(str: String) {
if str == "0" {
type = A()
} else {
type = B()
}
}
}
....
let obj = Demo(str: "0").type
print(obj.x)