2017-05-27 13 views
0

を入力し、なぜこの機能は私に次のエラー与えている:スカラ:再帰的価値listHumanのニーズが

recursive value listHuman needs type

def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = { 
    val listHuman = physicalResources.map{pr => totalHumanResources.find(_.handles.contains(pr.post)).filterNot(a=>listHuman.contains(a))} 
    return listHuman 
} 

を私はこれを実行しようとしましたが、それは私に別のエラーを与える:

val listHuman: List[Human] = physicalResources.map{pr => totalHumanResources.find(_.handles.contains(pr.post)).get}.filterNot(human=>listHuman.contains(human)) 

forward reference extends over definition of value listHuman

+0

@' filterNot(ヒト=> listHuman.contains(ヒト) '。予想されることになりますか? –

+0

はい、私はlistHumanが繰り返し要素を持たないようにします。これは私のアプローチでしたが、正しいかどうかはわかりませんでしたが、私がテストしようとしていたものでした。 –

+0

'Human'平等のためにはどのフィールドを考慮する必要がありますか? –

答えて

1

このエラーは、定数値または変数が宣言の前に使用されていることを意味します。たとえば、

val y = x + 2 
    val x = 5 

自分自身で定数値を定義しようとしていますか? constantの定義では不可能です。再帰を使用するにはdefを使用します。

1

あなたはfoldLeftをしたいと思われる、この作品ですか?

def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = { 
    physicalResources.foldLeft(Set.empty[Human]) { (l, pr) => 
    val applicableHuman = totalHumanResources.find(_.handles.contains(pr.post)) 
    l ++ applicableHuman 
    }.toList 
} 
+0

私が理解したところでは、あなたのコードは複製の権利を無視していますか?それは私が欲しいだけではありません。私は関数が重複を無視し、 'totalHumanResources'リストの中の次の" applicableHuman "を見つけることを望みます。 –

+0

これらの仮定はどちらも正しいです。つまり、Set型を使用して重複を排除するため、totalHumanResourcesに重複が含まれている場合、メソッドの最終結果に追加されません。適用可能なすべての人間は、最後の集合に集められ、その後、リストに変換されます。 foldLeftの良い出典があります:https://oldfashionedsoftware.com/2009/07/10/scala-code-review-foldleft-and-foldright/ – Tanjin

0

ここでの前提はsetHumanResourcesリターンHumanオブジェクトのユニーク/ distintリストを持つことです。このコードはfilterNot(a=>listHuman.contains(a))listHumanと定義して再帰的にlistHumanを参照し、意味的に不正な方法でと定義してこれを試みます。この重複排除は、以下の方法で適切に達成することができます。

  • リストをセットに変換してリストに戻して、listHuman.toSet.ToListのような重複を削除します。このメソッドが機能するには、Humanオブジェクトは、equalsメソッドをオーバーライドすることによって定義されたプロパティIDを持ちます。コードは次のようになります

    def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = { 
         val listHuman = physicalResources.map{pr => totalHumanResources.find(_.handles.contains(pr.post)) 
         listHuman.toSet.toList 
    } 
    

    Humanのサンプルクラスのデモを以下に示します。

    scala> class Human(val firstName: String, val lastName: String) { 
    | override def toString = this.firstName 
    | override def equals(that: Any): Boolean = that match { 
    |  case that: Human if that.firstName == this.firstName => true 
    |  case _ => false 
    | } 
    | } 
    defined class Human 
    
    scala> List(new Human("Peter", "Parker"), new Human("Peter", "Quill")).toSet.toList 
    res14: List[Human] = List(Peter) 
    
  • クラスHumanは、このアプローチに従うその後、equalsメソッドをオーバーライドして、その中に定義されたオブジェクトの等価性を持つことができない場合。それぞれHumanが2つのプロパティproperty1と​​によって一意に識別できると考えてください。 listHumanは以下の式で除算することができます。先に定義したHumanクラスの場合、firstNameプロパティとlastNameプロパティの両方を重複除外したい場合、コードは以下のようになります。

    listHuman.groupBy(x => (x.firstName, x.lastName)).map(_._2.head) 
    

    ので、新しいメソッドの定義は `listHuman`値の定義は、それ自体を参照され

    def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = { 
         val listHuman = physicalResources.map{pr => 
         totalHumanResources.find(_.handles.contains(pr.post)) 
         listHuman.groupBy(x => (x.property1, x.property2)).map(_._2.head) 
        }