Created
June 5, 2020 17:30
-
-
Save JonNorman/794ab875c810d30fca3b5604f7fd0726 to your computer and use it in GitHub Desktop.
Grouping Sublists
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.scalatest.FlatSpec | |
object GroupTask { | |
/** | |
* A function that can group a list of any type into sub-lists according to some condition. | |
* | |
* Because of the way we can pattern match on `List`s and extract their values via the "cons" operator - :: - we | |
* can build up our List of Lists as we go, adding a new list to the front whenever we find that the current element | |
* cannot be added to the current list. | |
* | |
* Once we have finished iterating over all of our input elements, we will end up with our lists in the wrong order | |
* (since we are prepending each successive list rather than appending it) - this is easily solved! We can just | |
* reverse the list when we're done 😀 | |
* | |
* @param canBeAddedToList - a function by which we can determine whether an element of that type can be added to a given list of that type or not. | |
* @param as - the initial list of our elements | |
* @tparam A - the type of the elements | |
*/ | |
def group[A](canBeAddedToList: (A, List[A]) => Boolean)(as: List[A]): List[List[A]] = | |
as.foldLeft(List(List.empty[A])) { (acc, a) => | |
acc match { | |
case currentList :: tail if canBeAddedToList(a, currentList) => | |
::(currentList :+ a, tail) | |
case _ => | |
::(::(a, Nil), acc) | |
} | |
} | |
.reverse | |
def alexisCondition(candidate: Int, group: List[Int], maximumInclusiveThreshold: Int = 10): Boolean = | |
group.sum + candidate <= maximumInclusiveThreshold | |
// we can combine our generic function and the "condition" function here to give us the function we want | |
def groupAlexis(numbers: List[Int]) = | |
group[Int](alexisCondition(_, _))(numbers) | |
} | |
class GroupTaskSpec extends FlatSpec { | |
"the example" should "work" in { | |
val input = List(1, 5, 3, 7, 6, 7, 3, 9, 3, 5) | |
val expected = List(List(1, 5, 3), List(7), List(6), List(7, 3), List(9), List(3, 5)) | |
val actual = GroupTask.groupAlexis(input) | |
assert(actual == expected) | |
} | |
"an empty list" should "return a list containing an empty list" in { | |
val input = List.empty[Int] | |
val expected = List(List.empty[Int]) | |
val actual = GroupTask.groupAlexis(input) | |
assert(actual == expected) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment