Functional Programming in Swit to distribute array

2019-07-09 16:56发布

问题:

I'm new to functional programming. My problem is that I have a main array and a fixed number of "destination" arrays. I would like to distribute the elements from the main array into the correct resulting array based on a certain value of each element.

I'm guessing that one approach would be to have one map function that goes through the main array elements, determines the correct "destination array" value (based on some logic) and then adds the elements to that array. However, I'm not sure this is very FP. After all, I'm causing a side-effect of changing arrays that are external to the main array that I'm mapping through.

How would you do this correctly in FP?

回答1:

Here's my idea: you can use reduce to eliminate side effects. Instead of creating the arrays before hand, create a dictionary of arrays.

For example, below is an extension that allows you to group elements of the original array by applying a function through them:

extension Array {
    func groupBy<T: Hashable>(f: Element -> T) -> [T: [Element]] {
        return self.reduce([T: [Element]]()) { (var aggregate, element) in
            let key = f(element)

            if aggregate[key] != nil {
                aggregate[key]!.append(element)
            } else {
                aggregate[key] = [element]
            }
            return aggregate
        }
    }
}

Example 1: group numbers by odd/even

let x = [1,2,3,4]
let y = x.groupBy {
    $0 % 2 == 0 ? "even" : "odd"
}

Example 2: group strings by length

let arr1 = ["lorem", "ipsum", "dolor", "sit", "amet"]
let arr2 = arr1.groupBy {
    $0.characters.count
}