如何解决此类映射的所有可能值排列
| 考虑这样的地图:Map(\"one\" -> Iterable(1,2,3,4),\"two\" -> Iterable(3,4,5),\"three\" -> Iterable(1,2))
我想获得Iterable
下元素的所有可能排列的列表,每个键一个元素。对于此示例,它类似于:
// first element of \"one\",first element of \"two\",first element of \"three\"
// second element of \"one\",second element of \"two\",second element of \"three\"
// third element of \"one\",third element of \"two\",first element of \"three\"
// etc.
Seq(Iterable(1,1),Iterable(2,2),Iterable(3,5,...)
有什么好办法做到这一点?
解决方法
val m = Map(\"one\" -> Iterable(1,2,3,4),\"two\" -> Iterable(5,6,7),\"three\" -> Iterable(8,9))
如果您想要每种组合:
for (a <- m(\"one\"); b <- m(\"two\"); c <- m(\"three\")) yield Iterable(a,b,c)
如果您希望每个可迭代的对象一起前进,但在最短的迭代时间停止时停止:
(m(\"one\"),m(\"two\"),m(\"three\")).zipped.map((a,c) => Iterable(a,c))
如果您希望每个可迭代项都环绕起来,但在用尽最长的迭代器时停止:
val maxlen = m.values.map(_.size).max
def icf[A](i: Iterable[A]) = Iterator.continually(i).flatMap(identity).take(maxlen).toList
(icf(m(\"one\")),icf(m(\"two\")),icf(m(\"three\"))).zipped.map((a,c))
编辑:如果您想要任意数量的输入列表,那么最好使用递归函数。对于笛卡尔产品:
def cart[A](iia: Iterable[Iterable[A]]): List[List[A]] = {
if (iia.isEmpty) List()
else {
val h = iia.head
val t = iia.tail
if (t.isEmpty) h.map(a => List(a)).toList
else h.toList.map(a => cart(t).map(x => a :: x)).flatten
}
}
并替换zipped
,您需要以下内容:
def zipper[A](iia: Iterable[Iterable[A]]): List[List[A]] = {
def zipp(iia: Iterable[Iterator[A]],part: List[List[A]] = Nil): List[List[A]] = {
if (iia.isEmpty || !iia.forall(_.hasNext)) part
else zipp(iia,iia.map(_.next).toList :: part)
}
zipp(iia.map(_.iterator))
}
您可以用cart(m.values)
,zipper(m.values)
和zipper(m.values.map(icf))
尝试这些。
,如果您想使用笛卡尔积,那么我可以为某物列表提供解决方案。
xproduct (List (List (1,List (3,4,5),List (1,2)))
res3: List[List[_]] = List(List(1,1),List(2,List(3,List(4,List(1,2),5,2))
用Rex \'m调用它:
xproduct (List (m(\"one\").toList,m(\"two\").toList,m(\"three\").toList))
,看看这个答案。问题是要合并的列表数量固定,但是一些答案可以解决一般情况。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。