2016-05-12 10 views
2

ここでは、データ更新で更新されたデータを決定するシナリオを示します。ケースクラスオブジェクトのSeqはIDを持ち、ケースクラスはIDフィールドを除く属性のデータ比較を行うoverride equalsメソッドを持っています。更新されたデータエントリを見つけるには、私はDBからデータを取得する必要があります。そして、2つの配列の比較が必要である。更新されるオブジェクトを見つけるためのScalaのアプローチとは何ですか?Scalaでの2つのSeqの比較

ちょっと考えてみましょう:オブジェクトIDをキーとして、オブジェクトを値としてマップを作成すること。それはうまくいくかもしれない。

(更新)ここで私は、私はあなたが右理解していれば、あなたはすでにequalsをオーバーライドすることで、ハードワークのほとんどをやった

val existingDataList: Foo = ... 
val existingDataMap: Map[Long, Foo] = existingDataList.map(d => d.id -> d)(collection.breakOut) 

// To find out updated data  
val updatedData = inputData.filter(d => existingDataMap.get(d.id) != d) 

答えて

3

だから、あなたは、2つのコレクションを持っているが、あなたが見つけたいですそれらのオブジェクトのペア、同じIDを持つが、異なるデータ、右ですか? diffはあなたがここで欲しいものではありません。

このような何かがそれを行います。

(first ++ second) 
    .groupBy (_.id) 
    .mapValues (_.toSet) 
    .filterNot { case (_, v) => v.size != 2 } 
    .values 
    .map { v => v.head -> v.last } 

それはあなたの両方の要素が同じIDが、異なるデータを持っている(第一、第二)のようなタプルのリストを提供します。

これは、各コレクション内でidsが一意であり、各IDが両方のコレクションに存在することを前提としています。また

、あなたはコレクションは、同じサイズのものであり、IDののとまったく同じセットが含まれていることを保証することができれば、あなたはこのような何かを行うことができ、効率が低いが、少し単純:

 first.sortBy(_.id) 
     .zip(second.sortBy(_.id)) 
     .filterNot { case (a, b) => a == b } 
+0

いくつかの高度なScaleアプローチをお披露してくれてありがとう。 – TeeKai

4

を出てくる解決策がある - そしてもちろん、あなたはMUSTも相応hashCode例を上書き:

case class Thing(id:Long, foo:String, bar:Int) { 
    override def equals(that:Any):Boolean = { 
    that match { 
     case Thing(_, f, b) => (f == this.foo) && (b == this.bar) 
     case _ => false 
    } 
    } 

    override def hashCode:Int = { 
    // A quick hack. You probably shouldn't do this for real; 
    // set id to 0 and use the default hashing algorithm: 
    ScalaRunTime._hashCode(this.copy(id = 0)) 
    } 
} 

は、今、私たちはいくつかのThingインスタンスを定義

val t1 = Thing(111, "t1", 1) 
val t1c = Thing(112, "t1", 1) // Same as t1 but with a new ID 
val t2 = Thing(222, "t2", 2) 
val t3 = Thing(333, "t3", 3) 
val t4 = Thing(444, "t4", 4) 
val t4m = Thing(444, "t4m", 4) // Same as t4 but with a modified "foo" 

のは、シーケンスのカップルしてみましょう:

val orig = Seq(t1, t2, t3, t4) 
val mod = Seq(t1c, t2, t3, t4m) 

をそして今diffは、私たちが知る必要があるすべて伝えます:

mod.diff(orig) 
// => returns Seq(t4m) - just what we wanted 
+0

それは動作します。そして、はい、私はhashCodeメソッドも書きました。 – TeeKai