2016-03-05 9 views
5

मैं एक सहायक विधि buildChain जो अनिवार्य रूप से है कि वे इंटरफ़ेस IChain<T> लागू दिया वस्तुओं की एक श्रृंखला बनाता है बनाया है और ठेके next सदस्यसरल या अधिक कार्यात्मक रास्ता

कोड निर्धारित किया है

interface Chain<T> { 
    var next: T? 

    operator fun plus(next: T): T? 
} 

fun <T : Chain<T>> buildChain(first: T, vararg members: T): T { 
    var next: T? = null 
    members.forEachIndexed { i, t -> 
     if (i == 0) { 
      next = first + t 
     } else { 
      next = next?.run { this + t } 
     } 
    } 
    return first 
} 

कार्यान्वयन उदाहरण

data class Person(val name: String) : Chain<Person> { 
    override var next: Person? = null 

    override fun plus(next: Person): Person? { 
     this.next = next 
     return next 
    } 
} 

fun createPersonChain() 
     = buildChain(Person("Bob"), Person("Bitzy"), Person("Blitzy")) 

implementaion उत्पादन उदाहरण

@JvmStatic fun main(args: Array<String>) { 
    var first = createPersonChain() 
    // first.name = "Bob" 
    // first.next.name = "Bitzy" 
    // first.next.next.name = "Blitzy" 
} 

वहाँ implementaion उपयोग ही रखते हुए ऊपर code प्राप्त करने के लिए एक functional या simpler रास्ता नहीं है?

उत्तर

8

एक कार्यात्मक idiom fold आपकी आवश्यकताओं को अच्छी तरह से उपयुक्त बनाता है: यह प्रारंभिक आइटम लेता है और फिर अन्य वस्तुओं पर पुनरावृत्त होता है, जो संचित मूल्य को बनाए रखता है, जिसे आपके द्वारा प्रदान किए जाने वाले प्रत्येक आइटम पर संसाधित किया जा रहा है।

कोटलिन में, यह fold extension functionIterable, Sequence या Array के लिए है।

आप निम्नलिखित तरीके से उपयोग कर सकते हैं: क्योंकि plus अपने Chain<T> रिटर्न में नल मान (वैसे, है,

fun <T : Chain<T>> buildChain(first: T, vararg members: T): T { 
    members.fold(first as T?) { acc, i -> acc?.let { it + i } } 
    return first 
} 

यहाँ first as T? डाली संचायक प्रकार के लिए की जरूरत है नल T? के रूप में अनुमान लगाया जा करने के लिए यह आवश्यक है?)।

तुम भी foldRight उपयोग कर सकते हैं, जो सिर्फ विपरीत क्रम में दोहराता:

fun <T : Chain<T>> buildChain(first: T, vararg members: T): T? = 
     (listOf(first) + members) 
      .foldRight(null as T?) { i, acc -> acc?.let { i + acc }; i } 
समान अर्थ विज्ञान के साथ

और देखते हैं reduce और reduceRight लेकिन पहली और संचायक के प्रारंभिक मूल्य के लिए पिछले आइटम क्रमशः का उपयोग कर। यहाँ reduceRight साथ उदाहरण है:

fun <T : Chain<T>> buildChain(first: T, vararg members: T): T? = 
     (listOf(first) + members).reduceRight { i, acc -> i.apply { plus(acc) } } 
+0

धन्यवाद हॉटकी एक आकर्षण की तरह काम करता है, अजीब बात यह है कि मैं सिर्फ गुना समारोह आज के दौरान सीखे गए है और यह श्रृंखलन कोड के साथ संयोजन में इस्तेमाल किया जा सकता का एहसास नहीं था –

0

apply{} की कोशिश करो। {} ब्लॉक में आपके विधियों को ';' से अलग किया गया है

Object().apply{ method1(); signUp(user) } 
संबंधित मुद्दे