Home > Net >  How to evenly spilt an array of strings into groups
How to evenly spilt an array of strings into groups

Time:10-18

I am coding an app that the user will input chores and cleaners. Then the data gets sorted. The chores should be evenly shuffled between the cleaners.

//this extension divides an array into chunks based on the number in the .chunked(by:)

var cleaners: [String] = ["person1", "person2"]


var chores: [String] = ["dishes", "laundry", "sweep patio", "dust", "trash","bathroom"]


var choresSorted = chores.chunked(by: cleaners.count)


extension Collection {

    func chunked(by distance: Int) -> [[Element]] {
        precondition(distance > 0, "distance must be greater than 0") // prevents infinite loop

        var index = startIndex
        let iterator: AnyIterator<Array<Element>> = AnyIterator({
            let newIndex = self.index(index, offsetBy: distance, limitedBy: self.endIndex) ?? self.endIndex
            defer { index = newIndex }
            let range = index ..< newIndex
            return index != self.endIndex ? Array(self[range]) : nil
        })

        return Array(iterator)
    }


print as [["dishes", "laundry"], ["sweep patio", "dust"], ["trash","bathroom"]]

So the problem is the chores are being grouped into 2s because there are 2 cleaners, I want to be able to sort them into 2 groups of 3 aka

print as [["dishes", "laundry", "sweep patio"], ["dust", "trash","bathroom"]]

PS I do not need to know how to shuffle them I already know how ill just use

chores.shuffle()

CodePudding user response:

You're chuncking your array into cleaners.count which is 2 in the example case. What you're looking for is the number of chores divided by the number of cleaners rounded into an integer value as below:

var choresSorted = chores.chunked(by: floor(chores.count / cleaners.count))

Also your extension code gave me cancer. Here's a cleaner implementation:

var cleaners: [String] = ["person1", "person2"]
var chores: [String] = ["dishes", "laundry", "sweep patio", "dust", "trash","bathroom"]

chores.shuffle()
var choresSorted = chores.chunked(by: floor(chores.count / cleaners.count))

extension Array {
    func chunked(into size: Int) -> [[Element]] {
        return stride(from: 0, to: count, by: size).map {
            Array(self[$0 ..< Swift.min($0   size, count)])
        }
    }
}

Extension code source

Note: for chorse.count values that are not modulo cleaners.count (doesn't divide into a round number) you can also check out the behavior of ceil instead of floor or simply round.

  • Related