如何解决压缩两个长度递减的列表
我得到了下面应该用scala解决的问题陈述: 两个元素列表,第一个的大小小于第二个。例如列表 1 有 2 个元素,列表 2 有 10 个元素。 需要将列表 1 的每个元素与第二个列表的两个元素进行映射。用于第一个元素的元素不应用于第二个元素,即它从第二个列表中获取两个唯一元素并返回第二个列表中的剩余元素以及映射元素列表。
scala> val list1 = List(1,2)
list1: List[Int] = List(1,2)
scala> val list2 = List(3,4,5,6,7,8,9)
list2: List[Int] = List(3,9)
预期输出
(List((1,3),(1,4),(2,5),6)),List(7,9))
解决方法
您从重复第一个列表的元素 n 次开始,对结果进行 flatMap 并用第二个集合压缩:
val list1 = List(1,2)
val list2 = List(3,4,5,6,7,8,9)
val zipped = list1
.flatMap(i => (1 to list1.size).map(_ => i))
.zip(list2)
val result = (zipped,list2.drop(zipped.size))
,
这是我个人更喜欢使用尾递归方法解决的问题。
/** Zips two lists together by taking multiple elements from the second list
* for each element of the first list.
*
* @param l1 The first (small) list.
* @param l2 The second (big) list.
* @param n The number of elements to take of second list for each element of teh first list,* must be greater than zero.
* @return A pair of the zipped list with the remaining elements of the second list,* wrapped in an option to catch the possibility than the second list was consumed before finishing.
*/
def zipWithLarger[A,B](l1: List[A],l2: List[B])(n: Int): Option[(List[(A,B)],List[B])] = {
@annotation.tailrec
def loop(remainingA: List[A],remainingB: List[B],count: Int,acc: List[(A,B)]): Option[(List[(A,List[B])] =
(remainingA,remainingB) match {
case (a :: as,b :: bs) =>
val newElement = (a,b)
if (count == n)
loop(remainingA = as,remainingB = bs,count = 1,newElement :: acc)
else
loop(remainingA,count + 1,newElement :: acc)
case (Nil,_) =>
Some(acc.reverse -> remainingB)
case (_,Nil) =>
// We consumed the second list beforing finishing the first one.
None
}
// Ensure n is positive.
if (n >= 1) loop(remainingA = l1,remainingB = l2,acc = List.empty)
else None
}
您可以看到运行 here 的代码。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。