如何使用scala通过基于一个列表元素分组来创建列表列表?

时间:2014-12-16 09:41:24

标签: list scala

我有以下列表结构 -

List(("localhost","esx","192.168.1.1","33.36","93.80", "vms can not be added"),
 ("star","esx","192.168.1.2","62.61","47.20","vms can be added"),
 ("mars","esx","192.168.1.3","27.41","47.38","vms can be added), 
("moon","esx","192.168.1.4","23.58","69.40", "vms can not be added"))

我想要关注输出 -

List(("vms can be added",List(("star","esx","192.168.1.2","62.61","47.20"),
("mars","esx","192.168.1.3","27.41","47.38"))),

("vms can not be added",List(("localhost","esx","192.168.1.1","33.36","93.80"),
("moon","esx","192.168.1.4","23.58","69.40"))))

如何使用scala ???

获得以上输出

5 个答案:

答案 0 :(得分:2)

问题的第一部分非常简单

val l=List(
  ("localhost","esx","192.168.1.1","33.36","93.80", "vms can not be added"),
  ("star","esx","192.168.1.2","62.61","47.20","vms can be added"),
  ("mars","esx","192.168.1.3","27.41","47.38","vms can be added"),
  ("moon","esx","192.168.1.4","23.58","69.40", "vms can not be added"))


l.groupBy(_._6).toSeq

导致这个结果:

ArrayBuffer(   
  (vms can not be added,
    List(
      (localhost,esx,192.168.1.1,33.36,93.80,vms can not be added), 
      (moon,esx,192.168.1.4,23.58,69.40,vms can not be added))),     
  (vms can be added,
     List(
       (star,esx,192.168.1.2,62.61,47.20,vms can be added), 
       (mars,esx,192.168.1.3,27.41,47.38,vms can be added))))

这非常有效,因为它只会更改包含的结构,但会使值保持不变。

如果你真的想要改变这些值,你可以使用Shapeless library非常轻松地完成这项工作:

import shapeless._
import syntax.std.tuple._

l.groupBy(_._6).mapValues(_.map(_.take(5))).toList

给你这个:

List(   
  (vms can not be added,
    List(
      (localhost,esx,192.168.1.1,33.36,93.80), 
      (moon esx,192.168.1.4,23.58,69.40))),    
  (vms can be added,
    List(
      (star,esx,192.168.1.2,62.61,47.20), 
      (mars,esx,192.168.1.3,27.41,47.38))))

但是你会改变更多的价值,因此对垃圾收集器的压力会更大。因此,当每个元组中的附加值确实存在问题时,您应该只执行此操作。

注:

IntelliJ 14.0.1通过上面的无形表达获得了一些关注。它突出显示该行是错误的,但编译(并运行)它非常好。

答案 1 :(得分:1)

可能这就是你需要的:

val res = list
  .map(t => (t._6, (t._1, t._2, t._3, t._4, t._5)))
  .groupBy(t => t._1)
  .mapValues(v => v.map(t => t._2))
  .toList

//    List(
//        (vms can not be added,
//         List(
//             (localhost,esx,192.168.1.1,33.36,93.80), 
//             (moon,esx,192.168.1.4,23.58,69.40))), 
//        (vms can be added,
//         List(
//             (star,esx,192.168.1.2,62.61,47.20), 
//             (mars,esx,192.168.1.3,27.41,47.38))))

答案 2 :(得分:0)

如果您有二进制类别,则可以使用partition

val xs = List(("foo", "bar", 1), ("baz", "boing", 2), ("bla", "blub", 3))
val p = xs.partition(_._3 < 2)

...后跟map删除关键元素:

val x0 = p._1.map(tup => (tup._1, tup._2))
val y0 = p._2.map(tup => (tup._1, tup._2))

或者,使用filter

val x1 = xs.filter( _._3 <  2).map(tup => (tup._1, tup._2))
val y1 = xs.filter(!_._3 >= 2).map(tup => (tup._1, tup._2))

如果类别不是二进制,您可以使用groupByMap,这样您就可以访问各个键:

val m = xs.groupBy(_._3)
val x2 = m(1).map(tup => (tup._1, tup._2))
val y2 = m(2).map(tup => (tup._1, tup._2))
val z2 = m(3).map(tup => (tup._1, tup._2))

答案 3 :(得分:0)

考虑这一点是为了理解,

for ( (k,v) <- myList.groupBy(_._6)) 
  yield k -> v.map ( x => (x._1,x._2,x._3,x._4,x._5) )

还要考虑封装6-tupled值的case类,以获得更可读的引用,而不是例如x._5。即,

case class Server(name: String,
                  x:    String,
                  ip:   String,
                  seg1: String,
                  seg2: String,
                  msg:  String)

因此我们可以举例groupBy(msg)和最后map

map (x => x.copy(msg="") )

而不是引用每个参数。因此

val myList = List( 
  Server("localhost","esx","192.168.1.1","33.36","93.80", "vms can not be added"),
  Server("star",...), ...)

我们有那个

for ( (k,v) <- myList.groupBy(msg)) yield k -> v.map (x => x.copy(msg="") )

<强>更新

要将元组列表转换为案例类列表,请考虑此示例依赖于使用元组作为参数调用案例类中的tupled方法,

val a = List( (1,2,"a"), (3,4,"b") )
a: List[(Int, Int, String)] = List((1,2,a), (3,4,b))

case class c(i:Int, j:Int, s:String)
defined class c

a.map(c.tupled(_))
res: List[c] = List(c(1,2,a), c(3,4,b))

答案 4 :(得分:0)

我使用了以下 -

val myList = List(
("localhost","esx","192.168.1.1","33.36","93.80", "vms can not be added"),
("star","esx","192.168.1.2","62.61","47.20","vms can be added"),
("mars","esx","192.168.1.3","27.41","47.38","vms can be added), 
("moon","esx","192.168.1.4","23.58","69.40", "vms can not be added"))

myList.groupBy(_._6).map(x => (x._1,x._2.toList.map(p => 
("dnsName" -> p._1,"infrastructureType" -> p._2,
"hostId" -> p._3,"cpuUtilization" -> p._4, "memoryUtilization" -> p._5))))