2016-10-14 3 views
0

eine Funktion in Scala Schreiben, die ein Array/Tupeln/Seq verschiedener Arten von Werten und sortiert sie basierend auf ersten beiden Werte in jeder akzeptiert: IchScala Array von verschiedenen Arten von Werten

def sortFunction[T](input: Array[T]) = input(0)+ " " + input(1) 

Die Eingangswerte wie unten haben, sind:

val data = Array((1, "alpha",88.9), (2, "alpha",77), (2, "beta"), (3, "alpha"), (1, "gamma",99)) 

Dann rufe ich die sortFunction wie:

data.sortWith(sortFunction) 

Es unten Fehler geben:

- polymorphic expression cannot be instantiated to expected type; found : [T]scala.collection.mutable.Seq[T] ⇒ Int required: ((Int, String)) ⇒ ? Error occurred in an application involving default arguments. 
- type mismatch; found : scala.collection.mutable.Seq[T] ⇒ Int required: ((Int, String)) ⇒ ? Error occurred in an application involving default arguments. 

Was mache ich falsch oder wie komme ich damit klar? Ich wäre dankbar für irgendwelche Vorschläge.

+2

Ihre Sortierfunktion sortiert nichts. Es nimmt nur die ersten zwei Elemente aus dem 'Array' und versucht daraus einen' String' zu erzeugen. – jwvh

+0

sortfunction merkt, aber verkettet die gegebenen Eingaben – BDR

Antwort

1

Wenn Sie Art von Element kennen Array [T], Sie Pattern-Matching (bei gleichen Typs) verwenden können. Aber wenn Sie nicht wissen, kann Programm nicht entscheiden, wie Sie Ihre Daten sortieren.

Eine der Methoden ist nur String vergleichen wie unten.

object Hello{ 
    def sortFunction[T](input1: T, input2: T) = 
    input1 match { 
     case t : Product => 
     val t2 = input2.asInstanceOf[Product] 
     t.productElement(0).toString < t2.productElement(0).toString 
     case v => input1.toString > input2.toString 
    } 
    def main(args: Array[String]): Unit = { 


    val data = Array((1, "alpha",88.9), (2, "alpha",77), (2, "beta", 99), (3, "alpha"), (1, "gamma",99)) 

    println(data.sortWith(sortFunction).mkString) 
    } 
} 

Wenn Sie Artikel TARIT wissen wollen, sehen http://www.scala-lang.org/api/rc2/scala/Product.html

+0

danke das war wirklich hilfreich – SumB

1

Wenn Sie ein Array von Tupeln, die alle denselben arity, wie Tupel von (Int, String) haben, als Sie die Sortierfunktion jedoch so etwas wie

def sortFunction[T](fst: (Int, String), scd: (Int, String)) = fst._1 < scd._1 // sort by first element 

aussehen könnte, da Sie eine Array von Tupeln unterschiedlicher haben Der Scala-Compiler kann dies nur unter den nächstliegenden gemeinsamen Typ Product setzen. Dann können Sie sortieren wie folgt:

def sortFunction[T](fst: (Product), scd: (Product)) = fst.productElement(1).toString < scd.productElement(1).toString 

val data = Array((1, "alpha", 99), (2, "alpha"), (2, "beta"), (3, "alpha"), (1, "gamma")) 

data.sortWith(sortFunction) // List((1,alpha,99), (2,alpha), (3,alpha), (2,beta), (1,gamma)) 

Beachten Sie, dass dies wirklich schlecht Design ist. Sie sollten einen abstrakten Datentyp erstellen, der Ihre Daten strukturierter kapselt. Ich kann nicht sagen, wie es aussehen sollte, da ich weiß nicht, wo und wie Sie diese Informationen bekommen, aber hier ist ein Beispiel (genannt Foo, aber man sollte es natürlich nennen Bedeutung):

case class Foo(index: Int, name: String, parameters: List[Int]) 

Ich habe einfach angenommen, dass das erste Element in jedem Datenstück "Index" ist und das zweite Element "Name" ist. Ich nahm auch an, dass der Rest dieser Elemente immer ganze Zahlen sein wird und dass es null, eins oder mehrere von ihnen geben kann, also eine List (wenn es nur 0 oder 1 ist, wäre die beste Wahl Option).

Dann könnten Sie sortieren wie:

def sortFunction[T](fst: Foo, scd: Foo) = fst.index < scd.index 

oder

def sortFunction[T](fst: Foo, scd: Foo) = fst.name < scd.name 
+0

danke das funktioniert perfekt. – SumB

Verwandte Themen