2012-07-03 26 views

उत्तर

9

आप सामने arity पता नहीं है और एक भयानक भयानक हैक करना चाहते हैं, तो आप ऐसा कर सकते हैं:

def toTuple[A <: Object](as:List[A]):Product = { 
    val tupleClass = Class.forName("scala.Tuple" + as.size) 
    tupleClass.getConstructors.apply(0).newInstance(as:_*).asInstanceOf[Product] 
} 
toTuple: [A <: java.lang.Object](as: List[A])Product 

scala> toTuple(List("hello", "world")) 
res15: Product = (hello,world) 
+0

+1 को साफ करने के लिए बहुत उपयोगी करने के लिए नेतृत्व कर सकते हैं तारों से असाइनमेंट। यह var (ए, बी, सी) = toTuple (myIter.toList) के लिए काम नहीं करता है - कोई विचार? –

+1

रूबिस्ट्रो: उस उद्देश्य के लिए आप 'var list (a, b, c) = myIter.toList' –

14

आप वास्तव में नहीं अपने विधि Product वापस जाने के लिए के बाद से इस बेकार अस्पष्ट है चाहता हूँ। यदि आप लौटे ऑब्जेक्ट को टुपल के रूप में उपयोग करने में सक्षम होना चाहते हैं, तो आपको इसकी धैर्य जाननी होगी। तो आप क्या कर सकते हैं विभिन्न arities के लिए toTupleN विधियों की एक श्रृंखला है। सुविधा के लिए, आप इन्हें Seq पर अंतर्निहित विधियों के रूप में जोड़ सकते हैं।

इस बारे में कैसे:

class EnrichedWithToTuple[A](elements: Seq[A]) { 
    def toTuple2 = elements match { case Seq(a, b) => (a, b) } 
    def toTuple3 = elements match { case Seq(a, b, c) => (a, b, c) } 
    def toTuple4 = elements match { case Seq(a, b, c, d) => (a, b, c, d) } 
    def toTuple5 = elements match { case Seq(a, b, c, d, e) => (a, b, c, d, e) } 
} 
implicit def enrichWithToTuple[A](elements: Seq[A]) = new EnrichedWithToTuple(elements) 

और यह पसंद का उपयोग करें:

scala> List(1,2,3).toTuple3 
res0: (Int, Int, Int) = (1,2,3) 
14

हैं, के रूप में @dhg मनाया, आप की उम्मीद arity सामने तुम यहाँ कुछ उपयोगी कर सकते हैं पता है। shapeless आप लिख सकता है, का उपयोग करते हुए

scala> import shapeless._ 
import shapeless._ 

scala> import Traversables._ 
import Traversables._ 

scala> import Tuples._ 
import Tuples._ 

scala> List(1, 2, 3).toHList[Int :: Int :: Int :: HNil] map tupled 
res0: Option[(Int, Int, Int)] = Some((1,2,3)) 
+0

लेकिन 'यदि सूची की लंबाई संकलन समय में अपरिभाषित है Shapeless'' List' से एक 'Tuple' बनाने के लिए जिस तरह से प्रदान नहीं करता है, यह क्रम त्रुटियों –

3

आप चाहते हैं एक Tuple या बस एक Product। क्योंकि बाद के लिए:

case class SeqProduct[A](elems: A*) { 
    override def productArity: Int = elems.size 
    override def productElement(i: Int) = elems(i) 
} 

SeqProduct(List(1, 2, 3): _*) 
+0

का उपयोग भी कर सकते हैं' टुपल 'की भी इच्छा है, इसलिए मैं' FunctionX.tupled' का उपयोग कर सकता हूं, जिसे वास्तव में 'TupleX' की आवश्यकता होती है, 'उत्पाद' नहीं (नोट भी 'ProductX')। – metasim

1

@ किम स्टीबेल के विचार के आधार पर, मैंने एक सरल उपयोगिता लिखी जो सीक से ट्यूपल बनाता है।

import java.lang.reflect.Constructor 

/** 
* Created by Bowen Cai on 1/24/2015. 
*/ 
sealed trait Product0 extends Any with Product { 

    def productArity = 0 
    def productElement(n: Int) = throw new IllegalStateException("No element") 
    def canEqual(that: Any) = false 
} 
object Tuple0 extends Product0 { 
    override def toString() = "()" 
} 

case class SeqProduct(elems: Any*) extends Product { 
    override def productArity: Int = elems.size 
    override def productElement(i: Int) = elems(i) 
    override def toString() = elems.addString(new StringBuilder(elems.size * 8 + 10), "(" , ",", ")").toString() 
} 

object Tuples { 

    private[this] val ctors = { 
    val ab = Array.newBuilder[Constructor[_]] 
    for (i <- 1 to 22) { 
     val tupleClass = Class.forName("scala.Tuple" + i) 
     ab += tupleClass.getConstructors.apply(0) 
    } 
    ab.result() 
    } 

    def toTuple(elems: Seq[AnyRef]): Product = elems.length match { 
    case 0 => Tuple0 
    case size if size <= 22 => 
     ctors(size - 1).newInstance(elems: _*).asInstanceOf[Product] 
    case size if size > 22 => new SeqProduct(elems: _*) 
    } 

} 
+0

धन्यवाद, @xKommando। यही वह चीज है जिसकी मुझे जरूरत थी। क्योंकि मैं _toTuple_ को _AnyRef_ के बजाय _Any_ के अनुक्रम पर लागू करने के लिए चाहता था, मैंने _Seq [Any] _ के साथ elems के प्रकार को प्रतिस्थापित किया और 'आकार <= 22' के लिए अभिव्यक्ति को' val refs = के लिए बदल दिया (e <- elems) उपज e.asInstanceOf [AnyRef] ctors (आकार - 1)। newInstance (refs: _ *)। asInstanceOf [product] '(यहां उत्तर के आधार पर: [link] (http://stackoverflow.com/questions/16751484/स्केला है कि कैसे करने के लिए बल-रैपिंग-एक-पूर्णांक के रूप में एक-वस्तु)) – Phasmid

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^