Scala 不可变数组过滤条件
Scala Immutable Array Filter Condition
我在项目中使用邻接矩阵,我需要安全地移除边。
我正在从事的项目按以下方式使用矩阵:
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
的空条目进行操作(很明显)。我正在寻找解决方案。
重申一下,我想使用每条边的属性进行过滤,该属性可能为空,也可能不为空。有没有办法实现"skip if null"的一种类型?
感谢您的帮助和建议。
我认为您错过了真正的问题。
您处理空值的方式很好。问题是您正在尝试使用 filter
,它会从您的集合中删除元素,缩短它。
如果您想用空值替换集合中的某些元素,不可变的方法是使用 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
这会将您的边替换为空值。
Scala 具有不可变序列,Vector
。如果你使用它而不是数组,你可以拥有不变性和索引更新,就像这样:
var vec = Vector(null, 1.1, null, null)
vec = vec.updated(edgeIndex, null)
println(vec) // Vector(null, null, null, null)
您最好使用 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)))
我在项目中使用邻接矩阵,我需要安全地移除边。
我正在从事的项目按以下方式使用矩阵:
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
的空条目进行操作(很明显)。我正在寻找解决方案。
重申一下,我想使用每条边的属性进行过滤,该属性可能为空,也可能不为空。有没有办法实现"skip if null"的一种类型?
感谢您的帮助和建议。
我认为您错过了真正的问题。
您处理空值的方式很好。问题是您正在尝试使用 filter
,它会从您的集合中删除元素,缩短它。
如果您想用空值替换集合中的某些元素,不可变的方法是使用 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
这会将您的边替换为空值。
Scala 具有不可变序列,
Vector
。如果你使用它而不是数组,你可以拥有不变性和索引更新,就像这样:var vec = Vector(null, 1.1, null, null) vec = vec.updated(edgeIndex, null) println(vec) // Vector(null, null, null, null)
您最好使用 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)))