在Swift中,我想循环遍历一个数组,并将每个元素与前一个和/或下一个元素进行比较。对于每次比较,我要么产生一个新元素,要么什么都不产生。有没有“功能性”的方法来做这件事?
例如,我有一个Int
的数组,想找到所有的“局部最小值”。
我可以像这样依次做
let a = [ 1,2,2,3,5,4,2,5,7,9,5,3,8,10 ]
var i = 1
var r: [Int] = []
while i < a.count - 1 {
if a[i] < a[i+1] && a[i] < a[i-1] {
r.append(i)
}
i += 1
}
print(r)
// [6, 11]
我想知道是否有更简单或更直接的方法来做这件事。
7条答案
按热度按时间5cg8jx4n1#
一般来说,可以使用
dropFirst()
和zip()
并行遍历相邻的数组元素。下面是一个简单的例子,它生成数组元素之间的增量数组:为了计算局部最小值的索引,我们可以并行地迭代
a
、a.dropFirst()
和a.dropFirst(2)
。enumerated()
用于跟踪数组偏移,并且flatMap()
(在Swift 4.1中重命名为compactMap()
)用于仅选取对应于局部最小值的那些索引:dxxyhpgq2#
您可以将
while
循环和i
替换为for
循环和stride
。你可以使用一个过滤器,但它的可读性不如上面的代码:
0ejtzxu13#
我在寻找原始Q的一个变体,希望它能对其他人有所帮助。我需要Map数组中的每一项,同时考虑前面和后面的值:
用这个词搭配原始Q的方式不太好:
wnvonmuf4#
使用flatMap
06odsfpq5#
您还可以迭代索引并进行如下比较,
或者,类似这样的东西,
或者,短,
i86rm4rw6#
一个简单的for循环是否具有足够的可读性和可维护性?你可以在迭代时缓存中间值,这样你在每次迭代中只访问数组中的一个元素。如果你想将其推广到任何类似的类型,你可以将其实现为Array的扩展:
crcmnpdw7#
我认为马丁·R的回答很聪明,尽管我试着用另一种方式回答。