Help us understand the problem. What is going on with this article?

ScalaでCollection内オブジェクトの任意の条件で集合演算をする

More than 1 year has passed since last update.

※この記事は仕事用アカウントから個人用アカウントに移行した記事になります。

動機

Collection内のObjectのKeyだけ比較して集合演算したい!みたいなことって割とあると思います。

試してみた

keyvalueをもつcase classを定義し、keyの値で集合演算をしたい場合で考えます。
何も考えずにやると以下のようにうまくいきません。
list内の Obj(b,1) と del内の Obj(b,2) を同じオブジェクトと判定できず除外してくれません。

case class Obj(key: String, value: Int)

val list = List(
  Obj("a", 1),
  Obj("b", 2),
  Obj("c", 3)
)

val del = List(
  Obj("b", 11),
  Obj("b", 12),
  Obj("d", 13)
)

list diff del // => res0: List[Obj] = List(Obj(a,1), Obj(b,2), Obj(c,3))

直してみた

ObjequalshashCode をoverrideしてやればうまくいきます。良かったですね。
(equals内の実装は適当なのでプロダクションに入れるときはinstanceが異なる場合なども考慮してちゃんと実装しましょう)

case class Obj(key: String, value: Int) {
  override def equals(arg0: Any): Boolean = {
    key == arg0.asInstanceOf[Obj].key
  }

  override def hashCode(): Int = {
    key.hashCode
  }
}

val list = List(
  Obj("a", 1),
  Obj("b", 2),
  Obj("c", 3)
)

val del = List(
  Obj("b", 11),
  Obj("b", 12),
  Obj("d", 13)
)

list diff del // => res0: List[Obj] = List(Obj(a,1), Obj(c,3))

説明

Javaオブジェクトの比較には Object#equals, Object#hashCode を利用します。
Scalaでも同様にこれらのメソッドを任意に書き換えてあげれば良いようです。
今回は diff でしか検証してませんが、恐らく他の集合演算メソッドでも同様だと思います。

追記

コメントでご指摘頂いたとおり、case classのequals(), hashCode() をoverrideするのは注意が必要です。
特に理由が無ければ別の方法を取るべきだと思います。詳細はコメントを御覧ください。

元記事をアカウントごと消してしまったのでコメントが閲覧できなくなりました。
移行前にコメントだけ引用しておくべきだった・・・。

以上です。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away