Quickly and elegantly remove items from the list of case class classes

I have a nested case class structure in List

for simplicity will use the following example:

 case class Address(street: String, city: String, state: String, zipCode: Int) case class Person(firstName: String, lastName: String, addresses: List[Address]) case class Department(people: List[Person]) 

let's say that there is a List[Department] ; now if I want to create a new List[Department] by filtering Address for each Person that does not have a specific zipCode value; traditionally we can do the following

 def filterPersonsByAddress(dlist: List[Department]): List[Department] = { dlist.map { d => val people = d.people.map { p => p.copy(addresses = p.addresses.filterNot(_.zipCode == 38978))} d.copy(people=people) } } 

This approach does not work, because depending on the level of nesting, it can be large O (n ^ 2) or Big O (n ^ 3);

I am trying to learn lenses through Monocle . Until now, I have learned that lenses are useful when you need to โ€œmodifyโ€ a deeply nested case class structure, but have not yet found a way to โ€œchop offโ€ a certain part of the nested structure based on the condition and return a new structure. Is this possible for Monocle? Also, I'm not sure if lenses can help achieve a better Big O time?

+6
source share
1 answer

The following is essentially equivalent to your implementation in terms of performance, but it is more clear:

 import monocle.Traversal, monocle.macros.GenLens import monocle.function.all._, monocle.std.list._ val deptAddresses: Traversal[Department, List[Address]] = GenLens[Department](_.people) .composeTraversal(each) .composeLens(GenLens[Person](_.addresses)) val filterAddresses: Department => Department = deptAddresses.modify(_.filterNot(_.zipCode == 38978)) 

It just creates a workaround to go to each personโ€™s address list so that you can modify it based on the predicate. I'm not sure what the best way to do filtering is (since zip codes do not serve as unique indexes), but perhaps Julien will weigh with one.

+3
source

All Articles