Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Swift I would like to "join" two sequences in to a sequence of tuples

I would like to join two (or more) sequences that would then create a sequence of tuples. Where the first tuple would contain the first element of each sequence and the second tuple would contain the second elements, etc ... Below is an example function that takes two arrays and creates a third array of tuples. I then can use this sequence to process with map(), filter() and reduce() functions.

My example works, but is lacking in a bunch of ways. It is for arrays not for all sequences, It stops generating tuples when the first sequence runs out of elements. I would like nils to be in the tuples for the short sequences that can no longer provide elements. It is only for two arrays, I would like it to be for any number of sequences,

Partial solutions would be helpful. I'm a functional programming newbie so the proper name for this function would also be appreciated. Maybe its is already in the switfz library I just know what it is called. I chose "join" because it is roughly similar to the SQL "join" which also builds tuples (a.k.a. rows)

func join<T> (s1: Array<T>, s2: Array<T>) -> Array<(T,T)> {

var g1 = s1.generate();
var g2 = s2.generate();

var result:Array<(T,T)> = []

while let e1 = g1.next() {

    if let e2 = g2.next() {
        result.append((e1,e2))
    }
}
return result
}


class Hamming {
    class func compute(input: String, against: String) -> Int {
        return join(Array(input),Array(against)).reduce(0){ return ($1.0 != $1.1) ? $0 + 1 : $0 }
    }
}

Hamming.compute("abcde","abcdf")  // 1
like image 647
ahalls Avatar asked Aug 06 '14 06:08

ahalls


People also ask

Why do we use tuples in Swift?

Tuples in Swift occupy the space between dictionaries and structures: they hold very specific types of data (like a struct) but can be created on the fly (like dictionaries). They are commonly used to return multiple values from a function call.

Is a tuple a sequence?

In mathematics, a tuple is a finite ordered list (sequence) of elements. An n-tuple is a sequence (or ordered list) of n elements, where n is a non-negative integer. There is only one 0-tuple, referred to as the empty tuple.

What is difference between tuple and array in Swift?

Both tuples and arrays allow us to hold several values in one variable, but tuples hold a fixed set of things that can't be changed, whereas variable arrays can have items added to them indefinitely.


1 Answers

There is already a function for that called Zip2:

var first = [0,1,2,3]
var second = ["zero", "one", "two", "three"]

Array(Zip2(first,second))
// (0, "zero"), (1, "one"), (2, "two"), (3, "three")

This function however does not pad with nil and it also uses the shortest of the two passed in sequences. Notice though that it does not require that the types match between the two sequences and that it takes any sequence, not just arrays.

Here is my own custom implementation of Zip2WithNilPadding:

struct Zip2WithNilPadding<T: SequenceType,U: SequenceType>: SequenceType {
    typealias Generator = GeneratorOf<(T.Generator.Element?, U.Generator.Element?)>

    let first: T
    let second: U

    init(_ first: T, _ second: U) {
        self.first = first
        self.second = second
    }

    func generate() -> Generator {
        var generator1: T.Generator? = first.generate()
        var generator2: U.Generator? = second.generate()

        return GeneratorOf<(T.Generator.Element?, U.Generator.Element?)>() {
            let element1 = generator1?.next()
            let element2 = generator2?.next()
            if element1 == nil && element2 == nil {
                return nil
            }
            else if element1 == nil{
                generator1 = nil
            }
            else if element2 == nil {
                generator2 = nil
            }
            return (element1, element2)
        }
    }
}

var first = [0,1,2]
var second = ["zero", "one", "two", "three", "four"]
Array(Zip2WithNilPadding(first, second))

If you have questions about the specific implementation let me know and I will try to clarify. This implementation should also help you in creating a Zip that takes an array of sequences. Unfortunately in that case they would all have to be a sequence of the same type because you can't have a variable amount of generics.

like image 137
drewag Avatar answered Sep 27 '22 22:09

drewag