我正在尝试为数组类型编写一个扩展,将索引 n 中的前 n 个索引相加。
let myArray = [1, 2, 3, 4, 5]
let mySumArray = myArray.sumNIndex()
print(mySumArray)
// returns [1,3,6,10,15]
我尝试过各种方法,但都在某些时候失败了。 例如,下面的示例会触发编译错误 “无法使用类型为‘(Int, _)’的参数列表调用‘reduce’”:
extension Array {
mutating func indexSum() {
var tempArray = [Any]()
for index in 1...self.count - 1 {
self[index] += self[.prefix(index + 2).reduce(0, +)]
}
}
}
此其他尝试触发另一个编译错误: “二元运算符‘+=’不能应用于两个‘元素’操作数”
extension Array {
mutating func indexSum() {
var tempArray = [Any]()
for index in 1...self.count - 1 {
self[index] += self[index - 1]
}
}
}
欢迎任何想法! 非常感谢您的帮助!
编辑:非常感谢@Martin 和@Carpsen,他们以两种不同的方式解决了这个问题
@Martin 使用 map 方法:
extension Array where Element: Numeric {
func cumulativeSum() -> [Element] {
var currentSum: Element = 0
return map {
currentSum += $0
return currentSum
}
}
}
@Carpsen 使用 reduce 方法:
extension Array where Element: Numeric {
func indexSum() -> [Element] {
return self.reduce(into: [Element]()) {(acc, element) in
return acc + [(acc.last ?? 0) + element]
})
}
}
最佳答案
主要问题是没有为元素定义加法运算符+
任意数组。您需要限制扩展方法,例如到
Numeric
元素的数组。
也没有必要使用Any
。
这里是一个可能的实现,作为一个非变异的方法:
extension Array where Element: Numeric {
func cumulativeSum() -> [Element] {
var currentSum: Element = 0
return map {
currentSum += $0
return currentSum
}
}
}
例子:
let intArray = [1, 2, 3, 4, 5]
print(intArray.cumulativeSum()) // [1, 3, 6, 10, 15]
let floatArray = [1.0, 2.5, 3.25]
print(floatArray.cumulativeSum()) [1.0, 3.5, 6.75]
以类似的方式,我们可以“累积加入”一个元素
字符串数组。 enumerated()
现在用于提供当前元素
与元素一起索引,用于决定是否
是否插入分隔符:
extension Array where Element == String {
func cumulativeJoin(separator: String) -> [Element] {
var currentJoin = ""
return enumerated().map { (offset, elem) in
if offset > 0 { currentJoin.append(separator) }
currentJoin.append(elem)
return currentJoin
}
}
}
例子:
let stringArray = ["a", "b", "c"]
print(stringArray.cumulativeJoin()) // ["a", "ab", "abc"]
print(stringArray.cumulativeJoin(separator: ":")) // ["a", "a:b", "a:b:c"]
关于arrays - Swift Array Extension 用 n-previous 值的总和替换索引 n 的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52613600/