Scala – 找到两个Seq不同的第一个位置
Scala带有很好的对应方法:
val a = scala.io.Source.fromFile("fileA").getLines().toSeq() val b = scala.io.Source.fromFile("fileB").getLines().toSeq() val areEqual = a.corresponds(b){_.equals(_)} if(areEqual) ... 我非常喜欢这种简洁. 是否已经定义了类似的方法,它还会向我报告两个序列不同的第一个位置? 即是否有更惯用的方式来写这样的东西: val result = ((seqA zip seqB).zipWithIndex).find{case ((a,b),i) => !a.equals(b)} match{ case Some(((a,i)) => s"seqA and seqB differ in pos $i: $a <> $b" case _ => "no difference" } 因为正如你所看到的那样,脖子上的血腥疼痛是难以理解的.如果我想使用三元组而不是元组元组,它会变得更糟: val result = (((seqA zip seqB).zipWithIndex) map {case (t,i) => (t._1,t._2,i)}).find{case (a,b,i) => !a.equals(b)} match{ case Some((a,i)) => s"seqA and seqB differ in pos $i: $a <> $b" case _ => "no difference" } 我知道diff方法.不幸的是,那个人忽视了元素的顺序. 解决方法
您可以使用indexWhere(参见
ScalaDoc),如下所示:
(as zip bs).indexWhere{case (x,y) => x != y} 例: scala> val as = List(1,2,3,4) scala> val bs = List(1,4,4) scala> (as zip bs).indexWhere{case (x,y) => x != y} res0: Int = 2 但请注意,如果一个Seq比另一个更长,所有基于zip的解决方案都可能没有差异(zip会截断更长的Seq) – 这可能是你需要的,也可能不是你需要的…… 更新:对于长度相等的Seqs,不同的方法如下: as.indices.find(i => as(i) != bs(i)) 这很好,因为它返回一个Option [Int],所以如果Seqs之间没有差异,它返回None而不是一个神奇的-1. 如果as比bs短,则其行为与其他解决方案相同,但如果更长则失败(当然,您可以采用最小长度). 但是,因为它通过索引处理Seqs,所以它只对IndexedSeqs表现良好. 更新2:我们可以通过使用lift处理不同的Seq长度,以便在按索引检索元素时获得选项: bs.indices.find(i => as.lift(i) != bs.lift(i)) 所以如果as = [1,2]和bs = [1,3],它们不同的第一个索引是2(因为这个元素在as中缺失).但是,在这种情况下,我们需要在最长的Seq而不是最短的Seq上调用索引 – 或者使用max显式检查哪个是最长的,例如 (0 until (as.length max bs.length)).find(i => as.lift(i) != bs.lift(i)) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |