如何将Seq的每个元素与其余元素配对?

时间:2018-12-30 12:34:02

标签: scala scala-collections

我正在寻找一种优雅的方法,将{"serialized_field_1":"VALUE1","serialized_field_2":"VALUE2"} 的每个元素与其余元素组合在一起以构成一个大型集合。 示例:Seq应该产生类似

的内容
Seq(1,2,3).someMethod

元素的顺序无关紧要。它不必是一个元组,Iterator( (1,Seq(2,3)), (2,Seq(1,3)), (3,Seq(1,2)) ) 也可以接受(尽管有点丑陋)。

请注意强调 large 集合(这就是我的示例显示Seq(Seq(1),Seq(2,3))的原因)。 另外请注意,这不是Iterator

想法?

编辑: 在我的用例中,数字应该是唯一的。如果一种解决方案可以消除重复现象,那很好,但无需额外付费。否则,可以接受骗子。

编辑2:最后,我使用了嵌套的combinations循环,而跳过了for的情况。没有创建新收藏。我赞成正确而简单的解决方案(“简单是最终的复杂性” -莱昂纳多·达·芬奇),但就问题的性质而言,即使最好的解决方案也是二次方的,有些解决方案创建了中间集合我想避免使用i == j,因为我正在处理的集合有将近50000个元素,二次时为25亿个。

5 个答案:

答案 0 :(得分:3)

以下代码具有恒定的运行时间(它懒惰地执行所有操作),但是访问结果集合的每个元素都具有恒定的开销(访问每个元素时,每次都必须计算索引移位):

def faceMap(i: Int)(j: Int) = if (j < i) j else j + 1

def facets[A](simplex: Vector[A]): Seq[(A, Seq[A])] = {
  val n = simplex.size
  (0 until n).view.map { i => (
    simplex(i),
    (0 until n - 1).view.map(j => simplex(faceMap(i)(j)))
  )}
}

示例:

println("Example: facets of a 3-dimensional simplex")
for ((i, v) <- facets((0 to 3).toVector)) {
  println(i + " -> " + v.mkString("[", ",", "]"))
}

输出:

Example: facets of a 3-dimensional simplex
0 -> [1,2,3]
1 -> [0,2,3]
2 -> [0,1,3]
3 -> [0,1,2]

此代码用simplices来表示所有内容,因为对于组合描述的单纯形,“省略一个索引”正好对应于face maps。为了进一步说明这个想法,以下是faceMap的作用:

println("Example: how `faceMap(3)` shifts indices")
for (i <- 0 to 5) {
  println(i + " -> " + faceMap(3)(i))
}

给予:

Example: how `faceMap(3)` shifts indices
0 -> 0
1 -> 1
2 -> 2
3 -> 4
4 -> 5
5 -> 6

facets方法使用faceMap来创建原始集合的惰性视图,该视图通过从被省略元素的索引开始将索引移位一个来省略一个元素。

答案 1 :(得分:2)

如果我正确理解了您想要的内容,那么在处理重复值(即要保留重复值)方面,这应该是可行的。给出以下输入:

import scala.util.Random

val nums = Vector.fill(20)(Random.nextInt)

这应该为您提供所需的东西:

for (i <- Iterator.from(0).take(nums.size)) yield {
  nums(i) -> (nums.take(i) ++ nums.drop(i + 1))
}

另一方面,如果您想删除公仔,我会转换为Sets:

val numsSet = nums.toSet
for (num <- nums) yield {
  num -> (numsSet - num)
}

答案 2 :(得分:1)

seq.iterator.map { case x => x -> seq.filter(_ != x) }

这是二次方的,但是我认为您不能做很多事情,因为最终,创建集合是线性的,您将需要N个。

答案 3 :(得分:0)

import scala.annotation.tailrec

def prems(s : Seq[Int]):Map[Int,Seq[Int]]={
  @tailrec
  def p(prev: Seq[Int],s :Seq[Int],res:Map[Int,Seq[Int]]):Map[Int,Seq[Int]] = s match {
    case x::Nil => res+(x->prev)
    case x::xs=> p(x +: prev,xs, res+(x ->(prev++xs)))
  }

  p(Seq.empty[Int],s,Map.empty[Int,Seq[Int]])
}

prems(Seq(1,2,3,4))
res0: Map[Int,Seq[Int]] = Map(1 -> List(2, 3, 4), 2 -> List(1, 3, 4), 3 -> List(2, 1, 4),4 -> List(3, 2, 1))

答案 4 :(得分:-2)

我认为您正在寻找permutations。您可以将结果列表映射到要查找的结构中:

function show(elementId) { 
   let divs = Array.from(document.querySelectorAll("[id ^= 'did']"));
   let imgs = Array.from(document.querySelectorAll("[id ^= 'iid']"));
   divs.forEach(d=>{d.style.display="none"})
   imgs.forEach(i=>{i.style.display="none"})
   document.getElementById("d"+elementId).style.display="block";
   document.getElementById("i"+elementId).style.display="block";
    }

请注意,最后的<div class="row"> <div class="col-4 col-sm-2 col-lg-2"> <div class="mx-2"><a id="me" class="trans-btn selected" onclick="show('id1');">Widget1</a></div> <div class="mx-2"><a id="me" class="trans-btn" onclick="show('id2');">Widget2</a></div> <div class="mx-2"><a id="me" class="trans-btn" onclick="show('id3');">Widget3</a></div> </div> <!--1st 3 divs--> <div class="col-8 col-sm-5 col-lg-5"> <div class="mx-2" id="did1"> <h3>Tabs with soft transitioning effect.</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar tempor. Cum sociis natoque penatibus et magnis dis parturient montes. </p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. </p> <a class="btn-warning" href="">Download</a> </div> <div class="mx-2" id="did2" style="display:none;"> <h3>Tabs Different effect.</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar tempor. Cum sociis natoque penatibus et magnis dis parturient montes. </p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. </p> <a class="btn-warning" href="">Download</a> </div> <div class="mx-2" id="did3" style="display:none;"> <h3>Tabs most of effect.</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar tempor. Cum sociis natoque penatibus et magnis dis parturient montes. </p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. </p> <a class="btn-warning" href="">Download</a> </div> </div> <!--next 3 divs(image section)--> <div class="col-12 col-sm-5 col-lg-5 last-sec"> <div class="mx-2" id="iid1"><img class="img-fluid" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/pin.png"/></div> <div class="mx-2" id="iid2" style="display:none;"><img class="img-fluid" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/cat.svg#blackcat"/></div> <div class="mx-2" id="iid3" style="display:none;"><img class="img-fluid" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/cat.svg#redcat"/></div> </div> </div>调用仅用于触发表达式的求值;否则,结果将是您要求的迭代器。

为了摆脱重复的头,Seq(1,2,3).permutations.map(p => (p.head, p.tail)).toList res49: List[(Int, Seq[Int])] = List((1,List(2, 3)), (1,List(3, 2)), (2,List(1, 3)), (2,List(3, 1)), (3,List(1, 2)), (3,List(2, 1))) 似乎是最简单的方法:

toList