## Modeling of basic Sets theory by Swift

In this article I’m trying to modelozie the basic Sets theory operation by programming , Sets theory is a fundamental concept helping Developers and Software architects to implement some good generic algorithms in order to solve problems in a generic vision, generally this kind of solution is useful and appreciated by Design Pattern architects.

To modelize things we selects very basic operations to implement , because basics are fundamental for extending model into a complex model , the abstraction is playing a big role in Design Pattern , that’s why I implement a generic class so later by extending It can be applied to lots of scenario.

In mathematics a Set is a collection of elements or objects with no necessary links between elements,

A = {1,7,8,25,17,9,30,42,70,18,25,99,55,88}

B = {2,27,8,88,18}

C = {“one”,”two”,”three”,”four"}

D = {🇨🇦,🇨🇿,🇨🇭,🇫🇷,🇺🇸}

//union of C and D

A ∪ B =  {1,2,7,8,25,27,17,18,9,30,42,70,18,25,99,55,88}

//Intersection of A and B

A B =  {8,88,18} //union of A and B

//union of C and D = C + D

D =  {“one”,”two”,”three”,”four”,🇨🇦,🇨🇿,🇨🇭,🇫🇷,🇺🇸

//Intersection of A and B

A C =

//substraction of A and B

A - B =  {1,7,25,17,9,30,42,70,25,99,55}

Now we are going to implement programmatically those basic ∪ (union) , ∩ (intersection), - (Subtract) Subset

A is a subset of B when all members of A are also member of B  ∀ x ∈ A => x ∈ B

A = {1,2,4,6,b} , B= {4,b,a,d,f,c}

∪ B = {1,2,4,6,b,a,d,f,c} => ∀ x ∈ A ∨ x ∈ B

B = {4,b} => ∀ x ∈ A ∧ x ∈ B

- B ={1,2,6} => ∀ x ∈ A ∧ x ∉ B

We create a generic class let’s call MathArray , to simplify things and in order to be able to check equality of elements (avoid to overload an additional equality operator) let’s suppose a generic type of Equatable class.

we add a list of items and a convenience initializer for default purpose

public class MathArray<T:Equatable>{

var mItems = [T]()

var items: [T]{

get {

return self.mItems

}

set{

self.mItems = newValue

}

}

public  convenience init(){

let arr = Array<T>()

self.init(array: arr)

}

public  init(array:[T]){

items = array

}

}

One of the great power of Swift is Overloading , those C++ developers are probably familiar with the nice C++ ability to define or redefine operators like +,-,==,&
for example it will be nice to define + operator to operate on any object we like , I mean by defining it we can apply it to A and B to get union
∪ as A+B , or we can define A - B or …

let union = A + B [or = A ∪ B]

let subtract = A - B

we can also check a collection if it’s a subset of another collection as
let isSubset = A
⊂ B

Now we implement all those nice operators in a global scoop

//give operator , this operator is exclusively used for debugging and test purpose

prefix func => <T>(right:MathArray<T>)->[T]{

return right.items

}

//Minus operator

func - <T>(left:MathArray<T>,right:MathArray<T>)->[T]{

let check = {

(x:T)->Bool in

return right.items.indexOf(x)==nil

}

return left.items.filter(check)

}

//subset operator

func  <T>(left:MathArray<T>,right:MathArray<T>)->Bool{

for element in left.items {

guard right.items.indexOf(element) != nil else { return false}

}

return true

}

//equal operator

func == <T>(left:MathArray<T>,right:MathArray<T>)->Bool{

for element in left.items {

guard right.items.indexOf(element) != nil else { return false}

}

for element in right.items {

guard left.items.indexOf(element) != nil else {return false}

}

return true

}

// union operator, + operator can be also replaced by

func + <T>(left : MathArray<T>,right : MathArray<T>)->[T]{

var result = [T]()

for element in left.items{

result.append(element)

}

for element in right.items{

result.append(element)

}

return result

}

//intersection operator

func  <T>(left : MathArray<T>,right : MathArray<T>)->[T]{

let check = {(x:T)->Bool in return right.items.indexOf(x) != nil}

return left.items.filter(check)

}

//Full class implementation , compiled & tested with Swift2 on XCODE 7.2

import Foundation

import UIKit

public class MathArray<T:Equatable>{

var mItems = [T]()

var items: [T]{

get {

return self.mItems

}

set{

self.mItems = newValue

}

}

public  convenience init(){

let arr = Array<T>()

self.init(array: arr)

}

public  init(array:[T]){

items = array

}

public static func getUnion<T:Equatable>(array1:[T],array2:[T])->[T]{

return MathArray<T>(array: array1)+MathArray<T>(array: array2)//add

}

public static func getInterset<T:Equatable>(array1:[T],array2:[T])->[T]{

return MathArray<T>(array: array1)  MathArray<T>(array: array2)

}

public static func isSetsEqual<T:Equatable>(array1:[T],array2:[T])->Bool{

return MathArray<T>(array: array1) == MathArray<T>(array: array2)

}

public static func isSubset<T:Equatable>(array1:[T],array2:[T])->Bool{

return MathArray<T>(array: array1)  MathArray<T>(array: array2)

}

public static func subtract<T:Equatable>(array1:[T],array2:[T])->[T]{

return MathArray<T>(array: array1) - MathArray<T>(array: array2)//minus

}

public static func getItemsForArray<T:Equatable>(array:[T])->[T]{

return =>MathArray<T>(array: array)

}

}

//Here we overload our Sets operators , notice overloading is only allowed in a global scoop
//so we define our Overloaded Operator out of our class

infix operator {}

prefix operator => {}

infix operator {}

prefix func => <T>(right:MathArray<T>)->[T]{

return right.items

}

//Minus operator

func - <T>(left:MathArray<T>,right:MathArray<T>)->[T]{

let check = {

(x:T)->Bool in

return right.items.indexOf(x)==nil

}

return left.items.filter(check)

}

//subset operator

func <T>(left:MathArray<T>,right:MathArray<T>)->Bool{

for element in left.items {

guard right.items.indexOf(element) != nil else { return false}

}

return true

}

//equal operator

func == <T>(left:MathArray<T>,right:MathArray<T>)->Bool{

for element in left.items {

guard right.items.indexOf(element) != nil else { return false}

}

for element in right.items {

guard left.items.indexOf(element) != nil else {return false}

}

return true

}

// union operator

func + <T>(left : MathArray<T>,right : MathArray<T>)->[T]{

var result = [T]()

for element in left.items{

result.append(element)

}

for element in right.items{

result.append(element)

}

return result

}

//intersection operator

func <T>(left : MathArray<T>,right : MathArray<T>)->[T]{

let check = {(x:T)->Bool in return right.items.indexOf(x) != nil}

return left.items.filter(check)

}

===========================================================

To test the class we can for example :

let A = [5,17,9,30,42,70,18,25,99,55,88]

let B = [5,25,61,54]

let result = MathArray<Int>.subtract(A, array2: B)

print("\(result)”)

print => [61,54]

© Xosrov 2016