我有一个类型为boolean的二维数组(不重要) 以非功能样式迭代数组很容易。 如何做FP风格?
var matrix = Array.ofDim[Boolean](5, 5)
对于ex,我想遍历给定列的所有行并返回与特定函数匹配的int列表。 示例:对于第3列,如果(4,3),(5,3)处的单元格与特定函数匹配,则迭代第1行到第5行以返回4,5。太多了
def getChildren(nodeId: Int) : List[Int] = {
info("getChildren("+nodeId+")")
var list = List[Int]()
val nodeIndex = id2indexMap(nodeId)
for (rowIndex <- 0 until matrix.size) {
val elem = matrix(rowIndex)(nodeIndex)
if (elem) {
println("Row Index = " + rowIndex)
list = rowIndex :: list
}
}
list
}
答案 0 :(得分:4)
怎么样?
(1 to 5) filter {i => predicate(matrix(i)(3))}
predicate
是你的职能吗?
请注意,使用(5,5)索引初始化的值从0到4。
更新:根据您的示例
def getChildren(nodeId: Int) : List[Int] = {
info("getChildren("+nodeId+")")
val nodeIndex = id2indexMap(nodeId)
val result = (0 until matrix.size).filter(matrix(_)(nodeIndex)).toList
result.forEach(println)
result
}
如果您愿意,也可以在装配工中移动印刷品,如果您希望完全按照示例中的那样翻转列表
答案 1 :(得分:2)
如果你对过滤器和拉链不熟悉,你可以坚持使用for-comprehension但是以更实用的方式使用它:
for {
rowIndex <- matrix.indices
if matrix(rowIndex)(nodeIndex)
} yield {
println("Row Index = " + rowIndex)
rowIndex
}
yield
根据for-comprehension的结果构建一个新集合,因此该表达式求值为您要返回的集合。 seq.indices
是一种等同于0 until seq.size
的方法。花括号允许您跨越多行而不使用分号,但如果需要,可以使其成为内联:
for (rowIndex <- matrix.indices; if matrix(rowIndex)(nodeIndex)) yield rowIndex
也许应该提一下,通常如果你在迭代一个数组,你根本不需要引用索引。你会做像
这样的事情for {
row <- matrix
elem <- row
} yield f(elem)
但是你的用例有点不寻常,因为它需要元素的索引,你通常不应该关注它们(使用数组索引本质上是一个快速而肮脏的黑客将数据元素与数字配对)。如果您想捕获并使用位置概念,最好使用带有此类字段的Map[Int, Boolean]
或case class
。
答案 2 :(得分:1)
def findIndices[A](aa: Array[Array[A]], pred: A => Boolean): Array[Array[Int]] =
aa.map(row =>
row.zipWithIndex.collect{
case (v,i) if pred(v) => i
}
)
通过提取仅在一行中查找索引的函数,您可以将其重构为更好一点:
def findIndices2[A](xs: Array[A], pred: A => Boolean): Array[Int] =
xs.zipWithIndex.collect{
case (v,i) if pred(v) => i
}
然后写
matrix.map(row => findIndices2(row, pred))