【问题标题】:Scala: Test whether Any variable can be iterated overScala:测试是否可以迭代任何变量
【发布时间】:2016-06-15 00:31:15
【问题描述】:

我想创建一个函数来检查 Any 类型的变量是否可以迭代。

def checkIterable(v: Any): Boolean = {
    // match with something?
}

然后我可以像这样使用它:

if (checkIterable(something)) {
    for (s <- something) {
        // do something with each element s of something
    }
}

对于ArrayListSeqIterable 类型的变量,这应该返回 true,基本上是任何定义了 foreach 函数的类型(看起来我不应该测试该功能的存在,除非它是唯一可能的方式...)

【问题讨论】:

  • 这是有道理的,因为Array 不是Iterable。也许,如果您解释一下您真正想做的事情,而不是从描述一个不起作用的解决方案开始,我们可能会提供更多帮助。
  • 检查它的一种方法是使用v.isInstanceOf[Iterable],但是,正如@Dima 所说,如果您更明确地说明您正在尝试做什么会更好。
  • 一开始为什么会有Any
  • @Dima 我收到了一个Any,因为我正在从某个地方读取数据,有时这些数据可以被迭代,例如ArrayList。我希望能够测试它是否可以迭代,如果可以的话,然后做一些事情。

标签: scala


【解决方案1】:

为什么不使用模式匹配?

something match {
  case xs: Iterable[_] => // do something with xs as iterable ...
  case _ => // ... that's something other
}

编辑

由于您想迭代结果但不知道里面是什么,我能想象的唯一方法是这样的:

def toList(x: Any): List[Any] = x match {
  case xs: Iterable[_] => xs.toList
  case xs: Array[_] => xs.toList
  case _ => List.empty
}

这样,无论您的输入是什么,您都会得到一个 List 并可以对其进行迭代。如果它不可迭代,它将是一个空列表。

toList("foo")        // List[Any] = List()
toList(List(1, 2, 3) // List[Any] = List(1, 2, 3)

【讨论】:

  • 这正是我一开始尝试的,但它只适用于Iterable类型的变量,而不是ArrayList,也可以迭代。
  • 我已经更新了我的答案,不是最好的,但应该可以。
  • 我也考虑过这一点,但我不必匹配每种可迭代的类型吗? Array, List, Seq, Iterable, ListBuffer, ...我希望有一种通用的方法来测试一个类型是否支持迭代
  • 不完全是,因为大多数类型都是由其他类型组成的,例如Seq 也是 Iterable。另一方面,如果你的类型太杂乱以至于你甚至可以区分任何类型,你需要在某个地方处理它,例如像这样的一些方法。另一种方法是改进您的文件读取过程并返回正确键入的实例。
  • 好的,我希望所有可迭代序列的某些父类型可以比较,或者测试是否为某些给定类型定义了foreach,以获得纯粹的通用解决方案。看起来这可能无法以优雅的方式实现。我不是从文件中读取,我使用的是移交 Any 实例的 API,因此无法控制之前键入它们。谢谢,会接受!
猜你喜欢
  • 1970-01-01
  • 2018-04-05
  • 1970-01-01
  • 2011-09-27
  • 2011-08-12
  • 1970-01-01
  • 1970-01-01
  • 2015-09-23
  • 2018-08-04
相关资源
最近更新 更多