2

Martin Oderskyは、配列を2つのコレクションに分割するためにこの例を示しています。

val people: Array[Person]
val (minors, adults) = people partition (_.age < 18)

class Person(val name: String, val age: Int)

3つ以上のアレイに分割するための最良の方法は何ですか?

val(マイナー、大人、シニア)=人のパーティション?? x <18、18 <x <65、x> 65 //?

4

4 に答える 4

7

ワンライナーでそれを行うことはおそらくあまりきれいではないでしょう。

val (minors, older) = people partition {_.age < 18}
val (adults, seniors) = older partition {_.age < 65}    
于 2012-07-09T22:17:47.843 に答える
3
def multiPartition[T: Manifest](xs: Traversable[T])(fs: T => Boolean *) = {
  val builders = Vector.fill(fs.length)(ArrayBuffer.empty[T])
  for (e <- xs) {
    val i = fs.indexWhere(f => f(e))
    if (i >= 0) builders(i) += e
  }
  builders.map(_.toArray)    
}

使用例は次のとおりです。

val Seq(minors, adults, seniors) = 
    multiPartition(people)(_.age < 18, _.age < 65, _ => true)

したがって、2番目の引数リストの各用語は「バケット」であり、_ => true「その他すべて」です。

これは配列を返します。ここで元のコレクションタイプを吐き出す非常によく似たバージョンを作成しましたが、それを配列でも機能させる方法はわかりません。

于 2012-07-10T00:35:15.943 に答える
2

これにより、未成年者、成人、および高齢者の質問で指摘したように、Tuple3が返されます。ただし、おそらくより効率的で一般的なアプローチがあります。

Tuple3(people.filter(_.age < 18), people.filter(p => p.age > 18 && p.age < 65), people.filter(_.age > 65))

于 2012-07-09T23:00:11.353 に答える
2

メソッドgroupByを使用できます。

case class Person(name: String, age: Int)

val people = Array(Person("A",1),Person("B",2),Person("C",14),Person("D",19),Person("E",70))

def typeByAge(p: Person): String = 
  if(p.age < 4) "BABY"
  else if(p.age < 18) "MINOR"
  else if(p.age < 65) "ADULT"
  else "OLD"

val g = people groupBy typeByAge

val (babys,minors,adults,olds) = (g("BABY"),g("MINOR"),g("ADULT"),g("OLD"))
于 2012-07-10T01:16:49.093 に答える