我是Scala的新手,但对Java很老,对使用像“Haskell”这样的FP语言有所了解。
在这里,我想知道如何使用Scala实现它。数组中有一个元素列表,所有这些元素都是字符串,我只想知道是否有一种方法可以在Scala中以FP方式执行此操作。这是我现在的版本......
def checkLength(vals: Array[String]): Boolean = {
var len = -1
for(x <- conts){
if(len < 0)
len = x.length()
else{
if (x.length() != len)
return false
else
len = x.length()
}
}
return true;
}
而且我很确定在Scala / FP中有更好的方法...
答案 0 :(得分:20)
list.forall( str => str.size == list(0).size )
编辑:这是一个尽可能通用的定义,还允许检查除长度以外的属性是否对所有元素都相同:
def allElementsTheSame[T,U](f: T => U)(list: Seq[T]) = {
val first: Option[U] = list.headOption.map( f(_) )
list.forall( f(_) == first.get ) //safe to use get here!
}
type HasSize = { val size: Int }
val checkLength = allElementsTheSame((x: HasSize) => x.size)_
checkLength(Array( "123", "456") )
checkLength(List( List(1,2), List(3,4) ))
答案 1 :(得分:7)
由于每个人似乎都很有创意,我也会有创意。 : - )
def checkLength(vals: Array[String]): Boolean = vals.map(_.length).removeDuplicates.size <= 1
请注意,removeDuplicates
可能在Scala 2.8上被命名为distinct
。
答案 2 :(得分:3)
提示:使用forall
确定集合中的所有元素是否都满足某个谓词(例如,长度相等)。
答案 3 :(得分:2)
如果你知道你的名单总是非空的,那么直接的表格就可以了。如果不这样做,可以很容易地将其添加到:
list match {
case x :: rest => rest forall (_.size == x.size)
case _ => true
}
现在,长度为零的列表返回true而不是抛出异常。
答案 4 :(得分:2)
list.groupBy{_.length}.size == 1
将列表转换为等长字符串组的映射。如果所有字符串具有相同的长度,则地图将仅包含一个这样的组。
这个解决方案的好处在于你不需要知道关于字符串长度的任何信息,也不需要将它们拼凑到第一个字符串中。它适用于空字符串,在这种情况下它返回false(如果这是你想要的......)
答案 5 :(得分:1)
这是另一种方法:
def check(list:List[String]) = list.foldLeft(true)(_ && list.head.length == _.length)
答案 6 :(得分:0)
我的€0.02
def allElementsEval[T, U](f: T => U)(xs: Iterable[T]) =
if (xs.isEmpty) true
else {
val first = f(xs.head)
xs forall { f(_) == first }
}
这适用于任何Iterable
,计算f可能的最小次数,并且当块不能被curry时,类型推断器可以推断块参数类型。
"allElementsEval" should "return true for an empty Iterable" in {
allElementsEval(List[String]()){ x => x.size } should be (true)
}
it should "eval the function at each item" in {
allElementsEval(List("aa", "bb", "cc")) { x => x.size } should be (true)
allElementsEval(List("aa", "bb", "ccc")) { x => x.size } should be (false)
}
it should "work on Vector and Array as well" in {
allElementsEval(Vector("aa", "bb", "cc")) { x => x.size } should be (true)
allElementsEval(Vector("aa", "bb", "ccc")) { x => x.size } should be (false)
allElementsEval(Array("aa", "bb", "cc")) { x => x.size } should be (true)
allElementsEval(Array("aa", "bb", "ccc")) { x => x.size } should be (false)
}
遗憾的是,head :: tail
模式匹配对于Iterables来说是如此不知所措。