我有一系列列表(假设以下3个列表),其中第一个元素都代表一个主键。
function checkusername(){
}
add_action( 'wp_ajax_checkusername', 'checkusername' );
add_action( 'wp_ajax_nopriv_checkusername', 'checkusername' );
我想将它们完全结合在一起,形成如下所示的新列表。您可以假设结果元组中的项目数预定为4
var A= List((1,"A"), (2,"B"), (3,"C"))
var B= List((1,"AA"), (2,"BB"), (3,"CC"), (4,"DD"))
var C= List((1,"AAA"), (3,"CCC"))
如何通过功能性方式和使用Scala实现这一目标?
答案 0 :(得分:1)
让我们说您正在获得输入列表,例如
var A= List((1,"A"), (2,"B"), (3,"C"))
var B= List((1,"AA"), (2,"BB"), (3,"CC"), (4,"DD"))
var C= List((1,"AAA"), (3,"CCC"))
然后通过应用以下功能
List(A,B,C).flatten.groupBy(_._1).map{
case (k,v) => k :: v.map(_._2)
}
您将获得输出
res0: scala.collection.immutable.Iterable[List[Any]] = List(List(2, B, BB), List(4, DD), List(1, A, AA, AAA), List(3, C, CC, CCC))
但是,如果您仍然想在输出中获取空字符串,则可以尝试以下
var A= List((1,"A"), (2,"B"), (3,"C"))
var B= List((1,"AA"), (2,"BB"), (3,"CC"), (4,"DD"))
var C= List((1,"AAA"), (3,"CCC"))
val intermediate = List(A,B,C).flatten.groupBy(_._1).map{
case (k,v) => k :: v.map(_._2)
}
val maxSize = intermediate.map(_.size).max
intermediate.map{
x => x.size== maxSize match {
case true =>
x
case false =>
x ::: List.fill(maxSize-x.size)("")
}
}
这将为您获取输出
res0: scala.collection.immutable.Iterable[List[Any]] = List(List(2, "B", "BB", ), List(4, "DD", , ), List(1, "A", "AA", "AAA"), List(3, "C", "CC", "CCC"))
Tuples有性能限制,并且大小限制为22,因此强烈建议您使用列表。
答案 1 :(得分:1)
您可以使用尾部递归来解决
var a= List((1,"A"), (2,"B"), (3,"C"))
var b= List((1,"AA"), (2,"BB"), (3,"CC"), (4,"DD"))
var c= List((1,"AAA"), (3,"CCC"))
val lst: List[List[(Int, String)]] = List(a, b, c)
def fun(input: List[List[(Int, String)]]): List[Any] = {
@tailrec
def itr(acc: List[Any], inp: List[List[(Int, String)]], key: Int, maxKey: Int): List[Any] = {
key match {
case x if x > maxKey => acc
case _ =>
itr(acc ::: List(key :: inp.map(itemLst => {
itemLst.find(_._1 == key).map(_._2).getOrElse("")
})), inp, key + 1, maxKey)
}
}
itr(List(), input, input.head.head._1, input.map(_.length).max)
}
println(fun(lst))
输出为
List(List(1, A, AA, AAA), List(2, B, BB, ), List(3, C, CC, CCC), List(4, , DD, ))
答案 2 :(得分:0)
正如评论中提到的那样,Scala中的元组受到限制,抽象化其笨拙可能会很麻烦。如果您希望这样做,可以看看Shapeless。
对于更直接(尽管不是很干净)的解决方案,将执行以下操作(使用针对两个不同 target 工具的实现):
val a = List((1,"A"), (2,"B"), (3,"C"))
val b = List((1,"AA"), (2,"BB"), (3,"CC"), (4,"DD"))
val c = List((1,"AAA"), (3,"CCC"))
def join4[K, V](empty: V)(pss: List[(K, V)]*): List[(K, V, V, V)] =
pss.reduceOption(_ ++ _).fold(List.empty[(K, V, V, V)])(_.groupBy(_._1).mapValues(_.map(_._2)).collect {
case (key, Nil) => (key, empty, empty, empty)
case (key, List(a)) => (key, a, empty, empty)
case (key, List(a, b)) => (key, a, b, empty)
case (key, List(a, b, c)) => (key, a, b, c)
case (key, list) => throw new RuntimeException(s"Group for $key is too long (${list.size} > 3)")
}.toList)
def join5[K, V](empty: V)(pss: List[(K, V)]*): List[(K, V, V, V, V)] =
pss.reduceOption(_ ++ _).fold(List.empty[(K, V, V, V, V)])(_.groupBy(_._1).mapValues(_.map(_._2)).collect {
case (key, Nil) => (key, empty, empty, empty, empty)
case (key, List(a)) => (key, a, empty, empty, empty)
case (key, List(a, b)) => (key, a, b, empty, empty)
case (key, List(a, b, c)) => (key, a, b, c, empty)
case (key, List(a, b, c, d)) => (key, a, b, c, d)
case (key, list) => throw new RuntimeException(s"Group for $key is too long (${list.size} > 4)")
}.toList)
join4("")(a, b, c)
join5("")(a, b, c)
您可以使用此代码on Scastie。
答案 3 :(得分:0)
正如在问题中提到的“我们可以假设结果元组中的项目数为predetermined to be 4
”,以下解决方案仅根据请求的工作返回元组:
给出的列表是:
var A= List((1,"A"), (2,"B"), (3,"C"))
var B= List((1,"AA"), (2,"BB"), (3,"CC"), (4,"DD"))
var C= List((1,"AAA"), (3,"CCC"))
在Scala REPL中:
scala> val list1 = List(A,B,C).flatten
list1: List[(Int, String)] = List((1,A), (2,B), (3,C), (1,AA), (2,BB), (3,CC), (4,DD), (1,AAA), (3,CCC))
scala> val list2 = List(A,B,C).flatten.map(x=>x._2.toArray).flatten.distinct
list2: List[Char] = List(A, B, C, D)
然后使用上面的two lists
,可以如下获得所需的resultList
:
scala> val resultList =
list2.map(x=>list1.filter(y=>y._2.contains(x))).map{
case List() =>
case List((a,b)) => (a,b,"","")
case List((a,b),(_,c))=>(a,b,c,"")
case List((a,b),(_,c),(_,d)) =>(a,b,c,d)
}
resultList: List[Any] = List((1,A,AA,AAA), (2,B,BB,""), (3,C,CC,CCC), (4,DD,"",""))
但是,如果我们确实关心empty string ""
中each tuple
的位置,那么代码会有点冗长,因为我们必须考虑case语句中所有组合的情况,并且条件{{1 }},如下所示:
pattern matching
但是,应该注意的是,在使用元组进行此类操作时,类型信息将丢失并且难以用结果元组列表处理。最好改用List等其他数据结构。但是,这是根据问题中提到的要求解决的。