- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要将传入对象的类型与一组预定义对象相交。
原始方法是为每个预定义类型扫描传入集合:
trait Field
class Field1 extends Field
class Field2 extends Field
class Field3 extends Field
...
class FieldManager(shownFields:Iterable[Field]) {
var hiddenFields = new ArrayBuffer[Field]
var found = false
for (sf <- shownFields) {
if (sf.isInstanceOf[Field1]) {
found = true
break
}
if (!found)
hiddenFields+=new Field1
for (sf <- shownFields) {
if (sf.isInstanceOf[Field2]) {
found = true
break
}
if (!found)
hiddenFields+=new Field2
for (sf <- shownFields) {
if (sf.isInstanceOf[Field3]) {
found = true
break
}
if (!found)
hiddenFields+=new Field3
...
}
哇,这对 Scala 来说太冗长了!应该有更短的方法。类似于 C++ 中的函数模板:
class FieldManager {
vector<Field*> hiddenFields, shownFields;
template<class T>
void fillHiddenType() {
FOR_EACH(Field *, field, shownFields) {
if (dynamic_cast<T*>(field))
return
hiddenFields.push_back(new T)
}
}
void fillHidden() {
fillHiddenType<Field1>();
fillHiddenType<Field2>();
fillHiddenType<Field3>();
...
}
};
在这个 C++ 示例中,我们提到每种类型只扫描一次。
好的,Scala 的类型参数也很好,让我们试试:
def fillHiddenType[T] {
for (sf <- shownFields)
if (sf.isInstanceOf[T])
return
hiddenFields+=new T
}
但是编译器不喜欢创建 T 实例:需要类类型但找到了 T
。尝试将实例作为参数传递,出现下一个问题 warning: abstract type T in type is unchecked since it is eliminated by erasure
and isInstanceOf[]
始终为真!类型 T 抽象得非常好,甚至 [T <: Field] 也不允许将其与我们的集合 shownFields 中的类型进行比较。
问题是:如何以紧凑的方式测试集合中给定类型的对象是否存在?
更新以下工作代码在 Scala 2.7.7 上进行了测试,这两个答案都很有用。谢谢你们!
//Scala 2.7.7 misses toSet members
implicit def toSet[T](i:Iterable[T]): Set[T] = {
val rv = new HashSet[T]
rv ++= i
rv
}
def filterOut[T](all:Iterable[T], toRemove:Set[T]) = {
all.filter(x => ! toRemove.contains(x))
}
def filterOutByType[T <: AnyRef](all:Iterable[T], toFilter:Set[T]):Iterable[T] = {
def toClass(x:AnyRef) = x.getClass.asInstanceOf[Class[T]]
val allTypes = all map toClass
val extraTypes = toSet(filterOut(allTypes, toFilter map toClass))
all.filter(extraTypes contains toClass(_))
}
最佳答案
找到具有给定类型的集合的第一个成员是微不足道的:
shownFields.find(_.isInstanceOf[Field1])
但这仍然会返回 Option[Field]
的实例,而不是 Option[Field1]
- 您需要强类型化。 collect 方法将在此处提供帮助:
showFields.collect{case x : Field1 => x}
这将返回一个 Iterable[Field1]
,然后您可以使用 headOption
选择可迭代对象的第一个元素作为 Option[Field1]
,或者 Some[Field1]
如果存在,或者 None
否则:
showFields.collect{case x : Field1 => x}.headOption
为了提高效率,而不是计算列表中的所有 Field1,我还通过 view
方法使其变得惰性:
showFields.view.collect{case x : Field1 => x}.headOption
然后如果未找到默认值,请使用 Options 提供的 getOrElse
方法:
showFields.view.collect{case x : Field1 => x}.headOption getOrElse (new Field1)
更新
我刚刚回顾了这个问题,如果您似乎希望 hiddenFields 包含 showFields 中没有成员的每个 Field 子类型的新实例。
查找 Iterable
中表示的所有类型:
val shownFieldTypes = showFields.map(_.getClass).toSet
(将其转换为集合强制使用唯一值)
如果您有一组您感兴趣的字段:
val allFieldTypes = Set(classOf[Field1], classOf[Field2], ...)
你可以减去找到缺失的:
val hiddenFieldTypes = allFieldTypes -- shownFieldTypes
这里的问题是你会被困在使用 newInstance 中,反射并不总是可取的......所以:
val protoHiddenFields = Set(new Field1, new Field2, ...)
val allFieldTypes = protoHiddenFields.map(_.getClass)
val hiddenFieldTypes = allFieldTypes -- shownFieldTypes
val hiddenFields = protohiddenFields.filter(hiddenFieldTypes contains _.getClass)
这种方法的美妙之处在于,如果您愿意,可以使用构造函数参数初始化您的原型(prototype)
关于scala - 如何测试基类型对象集合中是否存在一组类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3995364/
我有一个 if 语句,如下所示 if (not(fullpath.lower().endswith(".pdf")) or not (fullpath.lower().endswith(tup
然而,在 PHP 中,可以: only appears if $foo is true. only appears if $foo is false. 在 Javascript 中,能否在一个脚
XML有很多好处。它既是机器可读的,也是人类可读的,它具有标准化的格式,并且用途广泛。 它也有一些缺点。它是冗长的,不是传输大量数据的非常有效的方法。 XML最有用的方面之一是模式语言。使用模式,您可
由于长期使用 SQL2000,我并没有真正深入了解公用表表达式。 我给出的答案here (#4025380)和 here (#4018793)违背了潮流,因为他们没有使用 CTE。 我很欣赏它们对于递
我有一个应用程序: void deleteObj(id){ MyObj obj = getObjById(id); if (obj == null) { throw n
我的代码如下。可能我以类似的方式多次使用它,即简单地说,我正在以这种方式管理 session 和事务: List users= null; try{ sess
在开发J2EE Web应用程序时,我通常会按以下方式组织我的包结构 com.jameselsey.. 控制器-控制器/操作转到此处 服务-事务服务类,由控制器调用 域-应用程序使用的我的域类/对象 D
这更多是出于好奇而不是任何重要问题,但我只是想知道 memmove 中的以下片段文档: Copying takes place as if an intermediate buffer were us
路径压缩涉及将根指定为路径上每个节点的新父节点——这可能会降低根的等级,并可能降低路径上所有节点的等级。有办法解决这个问题吗?有必要处理这个吗?或者,也许可以将等级视为树高的上限而不是确切的高度? 谢
我有两个类,A 和 B。A 是 B 的父类,我有一个函数接收指向 A 类型类的指针,检查它是否也是 B 类型,如果是将调用另一个函数,该函数接受一个指向类型 B 的类的指针。当函数调用另一个函数时,我
有没有办法让 valgrind 使用多个处理器? 我正在使用 valgrind 的 callgrind 进行一些瓶颈分析,并注意到我的应用程序中的资源使用行为与在 valgrind/callgrind
假设我们要使用 ReaderT [(a,b)]超过 Maybe monad,然后我们想在列表中进行查找。 现在,一个简单且不常见的方法是: 第一种可能性 find a = ReaderT (looku
我的代码似乎有问题。我需要说的是: if ( $('html').attr('lang').val() == 'fr-FR' ) { // do this } else { // do
根据this文章(2018 年 4 月)AKS 在可用性集中运行时能够跨故障域智能放置 Pod,但尚不考虑更新域。很快就会使用更新域将 Pod 放入 AKS 中吗? 最佳答案 当您设置集群时,它已经自
course | section | type comart2 : bsit201 : lec comart2 :
我正在开发自己的 SDK,而这又依赖于某些第 3 方 SDK。例如 - OkHttp。 我应该将 OkHttp 添加到我的 build.gradle 中,还是让我的 SDK 用户包含它?在这种情况下,
随着 Rust 越来越充实,我对它的兴趣开始激起。我喜欢它支持代数数据类型,尤其是那些匹配的事实,但是对其他功能习语有什么想法吗? 例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
我一直在研究 PHP 中的对象。我见过的所有示例甚至在它们自己的对象上都使用了对象构造函数。 PHP 会强制您这样做吗?如果是,为什么? 例如: firstname = $firstname;
...比关联数组? 关联数组会占用更多内存吗? $arr = array(1, 1, 1); $arr[10] = 1; $arr[] = 1; // <- index is 11; does the
我是一名优秀的程序员,十分优秀!