我有简单的二维数组,每行中元素的数量不同。我的目标是找到具有优雅解决方案的下一个元素。
如果有最后一个元素,我们应该得到第一个。
[
[1, 0, 234, 345, 678],
[123, 456, 789],
[0, 9]
]
678 -> 123
9 -> 1
答案 0 :(得分:1)
如果mat
是一个嵌套数组,则mat.joined()
是所有嵌套元素的“惰性平面集合”。这建议解决任意集合的问题:
给出一个集合和该集合的一个元素,返回该元素的直接后继。该集合被视为循环,因此最后一个元素的后继者是第一个元素。
直接实现是(内联说明):
extension Collection where Element: Comparable {
func cyclicNext(after elem: Element) -> Element? {
// Find (first) index of given element
guard var idx = firstIndex(of: elem) else {
return nil // Element not present in collection
}
formIndex(after: &idx) // Advance index by one
if idx == endIndex { // If past the end ...
idx = startIndex // ... then jump back to the start
}
return self[idx]
}
}
如果元素在集合中出现多次,则返回第一次出现的后继者。
这可以应用于您的矩阵:
let mat: [[Int]] = [[1, 0, 234, 345, 678],
[123, 456, 789],
[0, 9]]
print(mat.joined().cyclicNext(after: 1)) // 0
print(mat.joined().cyclicNext(after: 678)) // 123
print(mat.joined().cyclicNext(after: 123)) // 456
print(mat.joined().cyclicNext(after: 9)) // 1
print(mat.joined().cyclicNext(after: 999)) // nil
它也可以应用于其他集合:
print([1, 3, 5, 7].cyclicNext(after: 3)) // 5
print([1, 3, 5, 7].cyclicNext(after: 7)) // 1
print("Hello World".cyclicNext(after: "W")) // "o"
print("Hello World".cyclicNext(after: "d")) // "H"
答案 1 :(得分:0)
一种可能的解决方案是将阵列弄平。
在操场上测试过:
let mat: [[Int]] = [[1, 0, 234, 345, 678],
[123, 456, 789],
[0, 9]]
func next(element: Int, in matrix: [[Int]]) -> Int? {
let flatten = matrix.flatMap({ $0 })
guard let index = flatten.firstIndex(of: element) else {
print("Element \(element) not found in matrix")
return nil
}
if index == flatten.endIndex - 1 {
return flatten.first
} else {
return flatten[index + 1 ]
}
}
let result1 = next(element: 678, in: mat)
print("End of subarray Test: \(result1)")
let result2 = next(element: 9, in: mat)
print("Last one Test: \(result2)")
let result3 = next(element: 66, in: mat)
print("Not present test: \(result3)")
let result0 = next(element: 1, in: mat)
print("First one test: \(result0)")
输出:
$>End of subarray Test: Optional(123)
$>Last one Test: Optional(1)
$>Element 66 not found in matrix
$>Not present test: nil
$>First one test: Optional(0)
我不知道它是否对您来说足够优雅。
一种优化将必须保留flatten
,而不必每次都重新计算。
答案 2 :(得分:0)
我相信这确实可以做到:
extension Array where Element == [Int] {
func element(after x: Int) -> Int? {
var arrayIndex = 0
while arrayIndex < self.count {
//If an array contains the searched element
if let xIndex = self[arrayIndex].firstIndex(where: { $0 == x }) {
//if the next element is in the same array
if xIndex < self[arrayIndex].count - 1 {
return self[arrayIndex][xIndex + 1]
}
//if the next element is in the next array
else if arrayIndex < self.count - 1 {
return self[arrayIndex + 1][0]
}
//if the x is the last element in the last array
else {
return self[0][0]
}
}
arrayIndex += 1
}
return nil
}
}
这是一些测试用例:
let mat = [
[1, 0, 234, 345, 678],
[123, 456, 789],
[0, 9]
]
mat.element(after: 678) //123
mat.element(after: 9) //1
mat.element(after: 1) //0
mat.element(after: 0) //234
mat.element(after: 3) //nil