Swift Running Sum

Swift running sum

The general combinator you're looking for is often called scan, and can be defined (like all higher-order functions on lists) in terms of reduce:

extension Array {
func scan<T>(initial: T, _ f: (T, Element) -> T) -> [T] {
return self.reduce([initial], combine: { (listSoFar: [T], next: Element) -> [T] in
// because we seeded it with a non-empty
// list, it's easy to prove inductively
// that this unwrapping can't fail
let lastElement = listSoFar.last!
return listSoFar + [f(lastElement, next)]
})
}
}

(But I would suggest that that's not a very good implementation.)

This is a very useful general function, and it's a shame that it's not included in the standard library.

You can then generate your cumulative sum by specializing the starting value and operation:

let cumSum = els.scan(0, +)

And you can omit the zero-length case rather simply:

let cumSumTail = els.scan(0, +).dropFirst()

Swift Array Running Total to x item

The closure called by reduce() has no information about the
current index.
Theoretically it is possible to create a closure that
uses a captured variable to "remember" how often it has been called:

func addFirst(var count : Int) -> (Int, Int) -> Int {
return {
count-- > 0 ? $0 + $1 : $0
}
}

let array = [1, 2, 3, 4, 5]
let sumOfFirstThreeItems = array.reduce(0, addFirst(3) )

But this would still run over the whole array and not just the
first 3 elements. There is no way to "stop" the process.

A much simpler way is to operate on an array slice:

let array = [1, 2, 3, 4, 5]
let sumOfFirstThreeItems = array[0 ..< 3].reduce(0) { $0 + $1 }

A slice is an Array-like type that represents a sub-sequence of any
Array, ContiguousArray, or other Slice.

Swift Int array every 3 elements sum

You can iterate your collection indices, add a guard to return zero in case it is less than 2 otherwise return the sum of the actual value + the last two values:

let numbers = [1,2,3,4,5,6,7,8,9,10,11,12]

let result = numbers.indices.map { index -> Int in
guard index > 1 else { return 0 }
return numbers[index-2...index].reduce(0,+)
}

result // [0, 0, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33]

or simply

let result = numbers.indices.map { $0 < 2 ? 0 : numbers[$0-2...$0].reduce(0,+) }

Can I do a running total with UILabels?

you can add observers for label/label2, and calculate in observeValue func

{
label.addObserver(self, forKeyPath: "text", options: .new, context: nil)
label2.addObserver(self, forKeyPath: "text", options: .new, context: nil)
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

result.text = ...
}

Cumulative sum of array items

Option 1

So if you want to get exact results as in your examples, you can use this method.
It will return you an array of partial sums, that you can later sum up to get the result:

private static long[] CumulativeSums(long[] values)
{
if (values == null || values.Length <= 1) return new long[0];

var results = new long[values.Length];
results[0] = values[0] + values[1];

for (var i = 1; i < values.Length - 1; i++)
{
results[i] = results[i - 1] + values[i + 1];
}

return results;
}

And the use it as this:

var numbers = new long[] { 12, 15, 17, 19 };
var sumOfCumulativeSums = CumulativeSums(numbers).Sum();

And sumOfCumulativeSums will be 134.

Option 2

But the actual correct representation of cumulative sum is: a, a+b, a+b+c, .... So if you want the correct representation of method that returns you proper cumulative sums, you can use this method instead:

public static long[] CumulativeSums(long[] values)
{
if (values == null || values.Length == 0) return new long[0];

var results = new long[values.Length];
results[0] = values[0];

for (var i = 1; i < values.Length; i++)
{
results[i] = results[i - 1] + values[i];
}

return results;
}

Edit

Hope this helps you to solve your problem in either of ways, and if you have any questions or edits about the code, please ask.

Finding the minimum number which when added to running sum of array is 1

Perform the accumulation in reverse, meaning:

Start with 1 and subtract values from the end of the array walking back to the the start of the array. Whenever you get a value that is less than 1, correct it to 1 before continuing the subtractions.

The value you get at completion of this algorithm is the minimum value of x you are looking for.

Implementation in a runnable JavaScript snippet:

function getMinX(arr) {
let x = 1;
for (let i = arr.length - 1; i >= 0; i--) {
x = x - arr[i];
if (x < 1) x = 1;
}
return x;
}

let arr = [-2, 3, 1, -5];
console.log(getMinX(arr)); // 4

Find the sum of an array in swift

Your issue is probably your Array declaration. You should declare is as an array of Int instead of an array of Any.

Sample Image

So your array declaration should be

@State private var numbers: [Int] = []

Array add previous index value to next index Swift 3

You can accomplish this by using a var total to keep track of the running total and use map to create a new array with each item replaced by total of it and the previous ones:

let array = [100.0, 10.0, 250.0]
var total = 0.0

let result = array.map { value -> Double in total += value; return total }
print(result)
[100.0, 110.0, 360.0]

Using a for loop:

This accomplishes the same task using a for loop to build up the result:

let array = [100.0, 10.0, 250.0]
var result = [Double]()
var total = 0.0

for value in array {
total += value
result.append(total)
}

print(result)
[100.0, 110.0, 360.0]


Related Topics



Leave a reply



Submit