我正在处理项目中的邻接矩阵,因此需要安全地移除边缘。
我正在从事的项目以下列方式使用矩阵:
Map[Agent, Array[Edge]]
。我想使用Array.filter
函数删除有问题的边缘。我这样做是为了避免使用索引或zipWithIndex
。
在矩阵中添加四个“ agent”并添加两个无向边后,这就是我的矩阵:
A1: null, 1.1, null, null,
A2: 1.1, null, null, null,
A3: null, null, null, 1.2,
A4: null, null, 1.2, null,
您会看到边缘是(A1,A2)和(A3,A4)。
要去除边缘(A1,A2),我正在使用它:
map = map.updated(a1, map(a2).filter(e => e != null && e.toAgent != a2))
但是,这将删除空条目(按预期)。这是使用上述技术去除边缘后矩阵的样子:
A1: 1.1,
A2:
A3: null, null, null, 1.2,
A4: null, null, 1.2, null,
空条目的作用是重要,因为它允许我快速在其正确位置插入新边。我正在寻找一种过滤出单个边缘的解决方案。
简单地做的问题:
map = map.updated(a1, map(a2).filter(e => e.toAgent != a2))
我正在对空条目进行操作,这会导致NullPointerException
(显然)。我正在寻找解决方案。
重申一下,我想使用可能为null或不为null的每个边的属性进行过滤。有没有一种方法可以实现“如果为空则跳过” ?
感谢您的帮助和建议。
答案 0 :(得分:1)
使用Option
而不是使用null
元素会更好。 Scala Option
是null
的更强大且类型安全的替代方案。
A1: None, Some(1.1), None, None,
A2: Some(1.1), None, None, None,
A3: None, None, None, Some(1.2),
A4: None, None, Some(1.2), None,
您可以filter
和Option
,它将仅测试Some
的值并跳过None
的值。
map = map.updated(a1, map(a2).map(_.filter(_.toAgent == a2)))
答案 1 :(得分:0)
我认为您错过了真正的问题。
处理null的方式很好。问题是您正在尝试使用filter
,它会从您的集合中删除元素,从而将其缩短。
如果您想用null替换集合中的某些元素,那么不变的方法是使用map
:
var arr = Array(null, 1.1, null, null)
arr = arr.map(e => if (e == 1.1) null else e)
println(arr.toList) // List(null, null, null, null)
但是,请注意一些事项。
scala中的数组是可变的。意思是,您可以执行以下操作:
arr(edgeIndex) = null
这会将您的边缘替换为null。
Scala具有不变的序列Vector
。如果使用它而不是数组,则可以具有不变性和索引更新,如下所示:
var vec = Vector(null, 1.1, null, null)
vec = vec.updated(edgeIndex, null)
println(vec) // Vector(null, null, null, null)