什么是Scala查找Array的所有元素是否具有相同长度的方法?

时间:2010-02-08 17:36:30

标签: scala functional-programming

我是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中有更好的方法...

7 个答案:

答案 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来说是如此不知所措。