arakweker
arakweker

Reputation: 1625

filling values in an Array

I have an array with and index (day) and a value (weight). I want to calculate 'values in between', so all the values that are 0.00 in myArray:

typealias Weights = (Double, Double)

var myArray: [Weights] = [ (0.0 , 25.4) , (1.0 , 0.0), (2.0 , 0.0), (3.0 , 0.0), (4.0 , 0.0), (5.0 , 30.3) , (6.0 , 33.5) , (7.0 , 0.0), (8.0 , 0.0), (9.0 , 51.2) , (10.0 , 0.0), (1q.0 , 0.0), (12.0 , 83.1) , (13.0 , 0.0), (14.0 , 0.0), (15.0 , 0.0), (16.0 , 143.0), (17.0 , 0.0), (18.0 , 0.0), (19.0 , 0.0), (20.0 , 0.0), (21.0 , 238.6) , (22.0 , 0.0), (23.0 , 0.0), (24.0 , 311.7) , (25.0 , 322.8) , (26.0 , 0.0), (27.0 , 0.0), (28.0 , 0.0), (29.0 , 460.9) , (30.0 , 0.0), (31.0 , 520.4), (32.0 , 0.0), (33.0 , 0.0),  (34.0 , 0.0), (35.0 , 642.2) , (36.0 , 694.0) , (37.0 , 0.0), (38.0 , 0.0), (39.0 , 0.0), (40.0 , 0.0), (41.0 , 0.0), (42.0 , 0.0), (43.0 , 988.3) , (44.0 , 1018.4) ]

For the calculations, it would be something like:

  1. values between day 5 and day 0 are 0.00
  2. 30.3 - 25.4 = 4.9
  3. 4.9 / 5 days = 0.98 per day

so the result for myArray would be:

[(0.0 , 25.4) , (1.0 , 26.4) , (2.0 , 27.4) , (3.0 , 28.4) , (4.0 , 28.3) , (5.0 , 30.3)... etc

How can I code this?

Upvotes: 0

Views: 181

Answers (2)

DVA
DVA

Reputation: 11

In-place approach using Swift 5

typealias Weights = (Double, Double)
var myArray: [Weights] =  [ (0.0 , 25.4) , (1.0 , 0.0), (2.0 , 0.0), (3.0 , 0.0), (4.0 , 0.0), (5.0 , 30.3) , (6.0 , 33.5) , (7.0 , 0.0), (8.0 , 0.0), (9.0 , 51.2) , (10.0 , 0.0), (11.0 , 0.0), (12.0 , 83.1) , (13.0 , 0.0), (14.0 , 0.0), (15.0 , 0.0), (16.0 , 143.0), (17.0 , 0.0), (18.0 , 0.0), (19.0 , 0.0), (20.0 , 0.0), (21.0 , 238.6) , (22.0 , 0.0), (23.0 , 0.0), (24.0 , 311.7) , (25.0 , 322.8) , (26.0 , 0.0), (27.0 , 0.0), (28.0 , 0.0), (29.0 , 460.9) , (30.0 , 0.0), (31.0 , 520.4), (32.0 , 0.0), (33.0 , 0.0),  (34.0 , 0.0), (35.0 , 642.2) , (36.0 , 694.0) , (37.0 , 0.0), (38.0 , 0.0), (39.0 , 0.0), (40.0 , 0.0), (41.0 , 0.0), (42.0 , 0.0), (43.0 , 988.3) , (44.0 , 1018.4), (45.0 , 0.0) ]
fillInBetween(&myArray)
print(myArray)

func fillInBetween(_ arr: inout [Weights])
{
    guard let firstNonZeroInd = arr.firstIndex(where: {$0.1 != 0}),
        let lastNonZeroInd = arr.lastIndex(where: {$0.1 != 0}) else { return }
    
    var ind = firstNonZeroInd
    while ind != lastNonZeroInd
    {
        let nextInd = arr[(ind+1)...].firstIndex(where: {$0.1 != 0})!
        let valueStep = (arr[nextInd].1 - arr[ind].1) / Double(nextInd - ind)
        for i in (ind+1)..<nextInd {
            arr[i].1 = arr[i-1].1 + valueStep
        }
        ind = nextInd
    }
}

Upvotes: 1

Vyacheslav
Vyacheslav

Reputation: 27211

I'm not sure that this question has got an easy solution for functional programming. Just simple for-each loop.

//: Playground - noun: a place where people can play

import UIKit

var str = "Hello, playground"
typealias Weights = (Double, Double)

var myArray: [Weights] = [ (0.0 , 25.4) , (1.0 , 0.0), (2.0 , 0.0), (3.0 , 0.0), (4.0 , 0.0), (5.0 , 30.3) , (6.0 , 33.5) , (7.0 , 0.0), (8.0 , 0.0), (9.0 , 51.2) , (10.0 , 0.0), (11.0 , 0.0), (12.0 , 83.1) , (13.0 , 0.0), (14.0 , 0.0), (15.0 , 0.0), (16.0 , 143.0), (17.0 , 0.0), (18.0 , 0.0), (19.0 , 0.0), (20.0 , 0.0), (21.0 , 238.6) , (22.0 , 0.0), (23.0 , 0.0), (24.0 , 311.7) , (25.0 , 322.8) , (26.0 , 0.0), (27.0 , 0.0), (28.0 , 0.0), (29.0 , 460.9) , (30.0 , 0.0), (31.0 , 520.4), (32.0 , 0.0), (33.0 , 0.0),  (34.0 , 0.0), (35.0 , 642.2) , (36.0 , 694.0) , (37.0 , 0.0), (38.0 , 0.0), (39.0 , 0.0), (40.0 , 0.0), (41.0 , 0.0), (42.0 , 0.0), (43.0 , 988.3) , (44.0 , 1018.4) ]

print(myArray)
var newArray: [Weights] = []
var nextNonZero = 0
var prevNonZero = nextNonZero
for index in prevNonZero..<myArray.count {
    let weight = myArray[index]
    guard weight.1 == 0 else {
        newArray.append(weight)
        continue
    }
    if index > nextNonZero {
        for innerIndex in index..<myArray.count {
            let innerWeight = myArray[innerIndex]
            let weightParam = innerWeight.1
            if weightParam != 0 {
                prevNonZero = nextNonZero
                nextNonZero = innerIndex
                break
            }
        }
    }
    print(prevNonZero, nextNonZero)
    let prevWeight = myArray[prevNonZero]
    let nextWeight = myArray[nextNonZero]
    let stepsNumber = Double(nextNonZero - prevNonZero)
    let difference = nextWeight.1 - prevWeight.1
    guard stepsNumber != 0 else {
        newArray.append((weight.0 , 0))
        continue
    }
    let step = difference / stepsNumber

    let differenceNumber = Double(index - prevNonZero)
    let differenceValue = step * differenceNumber
    let newValue = prevWeight.1 + differenceValue
    newArray.append((weight.0 , newValue))
}

print(newArray)

Upvotes: 1

Related Questions