2012-05-14 10 views
5

का केवल पहला तत्व रूपांतरण वहाँ की तरह कुछ सुपर Hacky कर के बिना एक सूची का केवल पहला तत्व को बदलने के लिए एक रास्ता है:एक स्काला सूची

val head = l1.head 
val tail = l1.tail 
val l2 = change(head) :: tail 

updated() है जैसे कि यह काम कर सकता है, लेकिन नहीं है

val head = l1.head 
val l2 = l.update(0, change(head)) 
कुछ

मैं खुशी होगी की तरह: एक सुधार की बहुत

val l2 = l1.updateHead(change(_)) 

वहाँ है इसके समान कुछ भी?

+3

'val l2 = change (l1.head) :: l1.tail' वास्तव में" सुपर हैकी "है? – stew

+0

शायद नहीं, हालांकि हर किसी ने मेरे लिए अच्छे दिखने वाले कई विकल्पों का सुझाव दिया। मुझे लगता है कि रॉबर्ट का पैटर्न मिलान दृष्टिकोण सबसे सरल है। – pr1001

उत्तर

15

आप

val l2 = l1 match{ 
    case Nil => Nil 
    case x::xs => change(x)::xs 
} 

इस तरह आप में चिंता करने की अगर head वास्तव में एक तत्व देता है

+0

पैटर्न मिलान चट्टानों! अच्छा है। –

8

आप हर मौके पर चर शुरू करने से बहुत कठिन अपने जीवन बना रहे हैं की जरूरत नहीं है मिलान पद्धति का उपयोग कर की कोशिश कर सकते। ऐसा मत करो!

विकल्प आप सूचीबद्ध दोनों काफी साफ हैं यदि आप अस्थायी चर परिचय नहीं है:

val l2 = change(l.head) :: l.tail 
val l2 = l.update(0, change(l.head)) 

न तो खाली सूचियों पर पूरी तरह से सुरक्षित है, लेकिन

val l2 = l.take(1).map(change) ::: l.drop(1) 

है।

आप कभी भी फिर भी अपनी खुद की विधि के साथ सूची को बेहतर बनाने के लिए स्वतंत्र हैं,:

class ReheadableList[A](xs: List[A]) { 
    def rehead[B >: A](f: A => B) = xs.take(1).map(f) ::: xs.drop(1) 
} 
implicit def lists_can_be_reheaded[A](xs: List[A]) = new ReheadableList(xs) 

(संपादित करें - बदल खाली सूची के साथ त्रुटियों से बचने के लिए)। अब आप केवल

val l2 = l.rehead(change) 
3

शायद ऐसा करने के कई तरीके हैं।

def listHeadLens[A] = new PartialLens[List[A], A] { 
    def apply: List[A] => Option[CoState[A, List[A]]] = { 
    case Nil => None 
    case x :: xs => Some(CoState(x, _ :: xs)) 
    } 
} 

मैं:

listHeadLens.set(list, newValue) 

जहां listHeadLens के रूप में परिभाषित किया गया है: नीचे एक स्काला आरईपीएल सत्र एक संस्करण

scala> val change = (x: Int) => x*2 
change: Int => Int = <function1> 

scala> val l = List(1,2,3) 
l: List[Int] = List(1, 2, 3) 

scala> l.headOption.map(x => change(x) :: l.drop(1)).getOrElse(Nil) 
res3: List[Int] = List(2, 2, 3) 
5

आंशिक लेंस (described in this paper) का उपयोग करना, आप की तरह कुछ लिख सकते हैं दिखा रहा है लगता है कि आंशिक लेंस स्कालाज़ 7 के लिए अपना रास्ता बना रहेगा। हालांकि मुझे यकीन नहीं है।

1

आप इसे ऐसा कर सकते हैं।

val list = List("1","2","3") 
def change(str : String) = Some("x") 

val nlist = (list.headOption.flatMap(change(_)).toList ::: list.tail) 

कंसोल में।

scala> val list = List("1","2","3") 
list: List[java.lang.String] = List(1, 2, 3) 

scala> def change(str : String) = Some("x") 
change: (str: String)Some[java.lang.String] 

scala> val nlist = (list.headOption.flatMap(change(_)).toList ::: list.tail)   
nlist: List[java.lang.String] = List(x, 2, 3)