2015-11-09 15 views
6

Ben bir örnek olarak aşağıdaki kullanacağı basitlik için bir Listverimli vaka sınıf yapısının bir Listesinden öğeleri kaldırmak ve zarif

bir iç içe case sınıflar yapıya sahip -

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]) 

List[Department] olduğunu söylüyor; şimdi zipCode değerine sahip olmayan her Person için Address filtreleyerek yeni bir List[Department] oluşturmak istemediysem; Geleneksel olarak biz

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) 
    } 
} 

Bu yaklaşım aşağıdakileri yapabilir bu (n^2) veya büyük O (n^3) Büyük O olabilir yuvalama seviyesine bağlı olarak ölçülebilir değildir;

Lensler'i Monocle aracılığıyla öğrenmeye çalışıyorum. Şimdiye kadar öğrendiklerim, Lensler, iç içe geçmiş bir case sınıf yapısını "değiştirmeniz" gerektiğinde faydalıdır, ancak henüz bir duruma bağlı olarak iç içe geçmiş yapının belirli bir kısmını "kesmek" ve yeni bir yapıya dönüşme yolu bulmamıştır. . Monocle ile bu mümkün mü? Ayrıca Lensler de daha iyi Big O zaman elde etmek için yardımcı olabilir mi emin değilim? Aşağıdaki

+1

Yeni departmanlarda bir departman bulunup bulunmayacağını belirlemek için tüm insanların tüm adreslerine bakmanız gerekiyorsa, o zaman bunun nasıl bir şey olduğunu göremiyorum ama O (#d * #p * #a) . –

+0

@TheArchetypalPaul: Yorumunuzla aynı fikirde değil. Bu, sorunun "verimli" bir bölümünü dışarıda bırakabilir; hala Lensler/Monocle'un orada yardımcı olup olmadığını görmek için bunu yapmanın zarif bir yolunu arıyor. biliyor musun? –

+0

'Lenses' adlı kavram hakkında bilgi edinin. Monocle/scalaz gibi bazı kütüphaneler onu uygular. – Maxim

cevap

3

performans açısından da uygulanması esasen eşittir, ama daha net tartışılabilir: Bu sadece dayanan değiştirmek, böylece adreslerin her kişinin listesine gezinmek için bir geçişi oluşturur

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)) 

yüklem. Filtrelemeyi gerçekleştirmenin daha iyi bir yolu olduğundan emin değilim (posta kodları benzersiz endeksler olmadığından), ama belki Julien bir taneyle tartılır.

İlgili konular