Scala:折叠二维数组
Scala: fold over two-dimensional array
给定一个可能很大的图像(或二维数字数组),我想遍历所有像素(或数字),例如计算所有黑色的(或 0 个值)。
我知道我可以简单地使用 for comprehension like
for (y <- 0 until img.height; x <- 0 until img.width) {
...
}
但是我需要一个可变变量来进行计数。这可能不是真正的问题,但假设我不想要这个并且想使用更实用的样式,我该怎么做而不创建具有宽度 x 高度元素的大型数据结构(换句话说保持内存 - 0 until img.height
和 0 until img.width
范围的效率)?
映射集合,将内部的转化为子计数,然后对它们求和:
scala> val m = Array(
Array("B","B","W"),
Array("W","W","B"),
Array("W","W","W")
)
m: Array[Array[String]] = Array(Array(B, B, W), Array(W, W, B), Array(W, W, W))
scala> m.map(_.count(_ == "B")).sum
res0: Int = 3
编辑
您可以使用
创建Stream
Stream.tabulate(img.height, img.width)(identity)
然后使用
stream.count(isBlack)
请注意 Stream.tabulate
最多接受 5 个维度(作为其第一个参数)。
您可以使用 for comprehension with ranges 将图像转换为像素序列:
for {
y <- 0 until img.height
x <- 0 until img.width
} yield image(x, y)
但这会在内存中创建一个完整的序列。为了让它变得懒惰,您可以查看范围:
for {
y <- (0 until img.height).view
x <- (0 until img.width).view
} yield image(x, y)
有了它,您可以在此序列上调用更高级别的函数来计算您需要的内容:
(
for {
y <- (0 until img.height).view
x <- (0 until img.width).view
} yield image(x, y)
).count(_.isBlack)
当然,您可以将此转换作为图像的隐式方法添加到像素序列中 class:
implicit class ImageOperations(image: Image) {
def toPixelSeq = for {
y <- (0 until img.height).view
x <- (0 until img.width).view
} yield image(x, y)
}
给定一个可能很大的图像(或二维数字数组),我想遍历所有像素(或数字),例如计算所有黑色的(或 0 个值)。
我知道我可以简单地使用 for comprehension like
for (y <- 0 until img.height; x <- 0 until img.width) {
...
}
但是我需要一个可变变量来进行计数。这可能不是真正的问题,但假设我不想要这个并且想使用更实用的样式,我该怎么做而不创建具有宽度 x 高度元素的大型数据结构(换句话说保持内存 - 0 until img.height
和 0 until img.width
范围的效率)?
映射集合,将内部的转化为子计数,然后对它们求和:
scala> val m = Array(
Array("B","B","W"),
Array("W","W","B"),
Array("W","W","W")
)
m: Array[Array[String]] = Array(Array(B, B, W), Array(W, W, B), Array(W, W, W))
scala> m.map(_.count(_ == "B")).sum
res0: Int = 3
编辑
您可以使用
创建Stream
Stream.tabulate(img.height, img.width)(identity)
然后使用
stream.count(isBlack)
请注意 Stream.tabulate
最多接受 5 个维度(作为其第一个参数)。
您可以使用 for comprehension with ranges 将图像转换为像素序列:
for {
y <- 0 until img.height
x <- 0 until img.width
} yield image(x, y)
但这会在内存中创建一个完整的序列。为了让它变得懒惰,您可以查看范围:
for {
y <- (0 until img.height).view
x <- (0 until img.width).view
} yield image(x, y)
有了它,您可以在此序列上调用更高级别的函数来计算您需要的内容:
(
for {
y <- (0 until img.height).view
x <- (0 until img.width).view
} yield image(x, y)
).count(_.isBlack)
当然,您可以将此转换作为图像的隐式方法添加到像素序列中 class:
implicit class ImageOperations(image: Image) {
def toPixelSeq = for {
y <- (0 until img.height).view
x <- (0 until img.width).view
} yield image(x, y)
}