2
\$\begingroup\$

I have created the following function in Swift for this library I am writing, which joins two arrays on a key (extracted using given closures), and then groups them by key in a [T:[S]] where S is the result type (also through a given closure).

extension Array {
    /// Joins the array with another array on a specific key, and then gives two matching elements to a closure to create a result type.
    /// Groups the result by key. Faster than `.join().groupBy()`
    ///
    /// :param: otherArray the other array to join
    /// :param: thisKeyClosure the closure that extracts the key from this array
    /// :param: otherKeyClosure the closure that extracts the key from the other array
    /// :param: resultClosure creates a resulttype from two inputtypes
    func groupJoin<R, S: Equatable, P>(otherArray: [R], thisKeyClosure: T -> S, otherKeyClosure: R -> S, resultClosure: (T,R) -> P) -> [S:[P]] {
        var result: [S:[P]] = [:]
        for thisItem in self {
            for otherItem in otherArray {
                let thisKey = thisKeyClosure(thisItem)
                if thisKey == otherKeyClosure(otherItem) {
                    if result[thisKey] == nil {
                        result[thisKey] = []
                    }
                    result[thisKey]!.append(resultClosure(thisItem, otherItem))
                }
            }
        }
        return result
    }
}

groupBy and join are methods in my own library, implementation groupBy and join

An example usage might be this method call:

class Person {
    var age: Int
    var name: String
}

class Dog {
    var owner: String
}

var arrayOfPeople: [Person] = [...]
var arrayOfDogs: [Dog] = [...]

let peopleWithDogs = arrayOfPeople.groupJoin(arrayOfDogs, {$0.name}, {$0.owner}, {$1})
// Joins both arrays on person.name and dog.owner, grouped in the array by name of owner, linked to an array of Dogs
\$\endgroup\$
  • \$\begingroup\$ Is this an extension on Array? \$\endgroup\$ – nhgrif Apr 12 '15 at 16:02
  • \$\begingroup\$ @nhgrif yes I'll add it sorry. \$\endgroup\$ – vrwim Apr 12 '15 at 16:02
  • \$\begingroup\$ A typical usage example might be constructive. And what do you mean by "Faster than .join().groupBy()" ? Does that refer to some or you own extension methods (not shown here)? \$\endgroup\$ – Martin R Apr 12 '15 at 16:38
  • \$\begingroup\$ Yes that refers to my own methods. I'll link my library on GitHub and add some example code. \$\endgroup\$ – vrwim Apr 12 '15 at 16:38
  • \$\begingroup\$ @MartinR edited my question \$\endgroup\$ – vrwim Apr 12 '15 at 16:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.