在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]
Run Code Online (Sandbox Code Playgroud)
我想知道是否有更简单或直接的方法来做到这一点.
Mar*_*n R 10
通常,可以使用dropFirst()和zip()并行遍历相邻的数组元素。这是一个简单的示例,它生成数组元素之间的增量数组:
let a = [ 1, 2, 2, 3, 5, 4, 2, 5, 7, 9, 5, 3, 8, 10 ]
let diffs = zip(a.dropFirst(), a).map(-)
print(diffs)
// [1, 0, 1, 2, -1, -2, 3, 2, 2, -4, -2, 5, 2]
Run Code Online (Sandbox Code Playgroud)
为了计算局部极小的指数,我们可以遍历a,a.dropFirst()
并a.dropFirst(2)在并行。enumerated()用于跟踪数组偏移量,并且flatMap()(compactMap()在 Swift 4.1 中重命名为)用于仅选择那些对应于局部最小值的索引:
let a = [ 1, 2, 2, 3, 5, 4, 2, 5, 7, 9, 5, 3, 8, 10 ]
let localMins = zip(a.enumerated().dropFirst(), zip(a, a.dropFirst(2))).flatMap {
$0.element < $1.0 && $0.element < $1.1 ? $0.offset : nil
}
print(localMins) // [6, 11]
Run Code Online (Sandbox Code Playgroud)
您还可以迭代索引并像这样进行比较,
for i in a.indices.dropFirst().dropLast()
{
if a[i] < a[a.index(after: i)],
a[i] < a[a.index(before: i)] {
r.append(i)
}
}
print(r)
// [6, 11]
Run Code Online (Sandbox Code Playgroud)
或者,像这样的事情,
let result = a.indices.dropLast().dropFirst().filter { i in
return a[i] < a[a.index(after: i)] &&
a[i] < a[a.index(before: i)]
}
print(r)
// [6, 11]
Run Code Online (Sandbox Code Playgroud)
或者,简短地说,
let result = a.indices.dropLast()
.dropFirst()
.filter { a[$0] < a[$0 + 1] &&
a[$0] < a[$0 - 1] }
print(result)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2388 次 |
| 最近记录: |