Как я могу получить совокупное среднее в структуре в Swift4? - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть следующая структура.

struct Fruit {
    var name: String
    var stateCd: Int
    var amt: Int
    var cumulativeAvg: Int
}

var fruit = [
    Fruit(name: "apple", stateCd: 0, amt: 100, cumulativeAvg: 0),
    Fruit(name: "apple", stateCd: 0, amt: 200, cumulativeAvg: 0),
    Fruit(name: "apple", stateCd: 1, amt: 100, cumulativeAvg: 0),
    Fruit(name: "apple", stateCd: 0, amt: 300, cumulativeAvg: 0)
]

Я хочу изменить значение столбца cumulativeAvg на совокупное среднее значение, если stateCd равно нулю.Если stateCd равен 1, предыдущее среднее значение берется без суммирования.

Ожидается, что измененные значения будут следующими:

Fruit(name: "apple", stateCd: 0, amt: 100, cumulativeAvg: 100),
Fruit(name: "apple", stateCd: 0, amt: 200, cumulativeAvg: 150),
Fruit(name: "apple", stateCd: 1, amt: 100, cumulativeAvg: 150),
Fruit(name: "apple", stateCd: 0, amt: 300, cumulativeAvg: 200)

Ответы [ 3 ]

0 голосов
/ 26 ноября 2018
fruit[0].cumulativeAvg = fruit[0].amt
for (i, f) in zip(1..., fruit.dropFirst()) {
    if f.stateCd == 1 {
        fruit[i].cumulativeAvg = fruit[i-1].cumulativeAvg
    } else {
        fruit[i].cumulativeAvg = (fruit[i-1].cumulativeAvg * i + fruit[i].amt) / (i+1)
    }
}
0 голосов
/ 26 ноября 2018

Это был бы лучший и более чистый подход к вашей проблеме.

struct Fruit {
    var name: String
    var stateCd: Int
    var amt: Double
    var cumulativeAvg: Double
}

Создайте другую структуру для хранения подсчета и среднего значения для определенного фрукта.

struct FruitStats {
    var count: Double
    var average: Double
}

Ведение словарякоторый отслеживает количество и среднее для каждого фрукта.

var fruitStats: [String: FruitStats] = [:]

var fruits = [
    Fruit(name: "apple", stateCd: 0, amt: 100, cumulativeAvg: 0),
    Fruit(name: "apple", stateCd: 0, amt: 200, cumulativeAvg: 0),
    Fruit(name: "apple", stateCd: 1, amt: 100, cumulativeAvg: 0),
    Fruit(name: "apple", stateCd: 0, amt: 300, cumulativeAvg: 0),
    Fruit(name: "orange", stateCd: 0, amt: 100, cumulativeAvg: 0),
    Fruit(name: "orange", stateCd: 1, amt: 100, cumulativeAvg: 0),
    Fruit(name: "orange", stateCd: 0, amt: 400, cumulativeAvg: 0)
]

let newFruits = fruits.map { (fruit) -> Fruit in
    var newFruit = fruit
    var fruitStat = fruitStats[fruit.name, default: FruitStats(count: 0, average: 0)]
    if fruit.stateCd == 0 {
        fruitStat.average *= fruitStat.count
        fruitStat.count += 1
        fruitStat.average = (fruitStat.average + fruit.amt)/fruitStat.count
    }
    newFruit.cumulativeAvg = fruitStat.average
    fruitStats[fruit.name] = fruitStat
    return newFruit
}

for fruit in newFruits {
    print(fruit.name, "\t", fruit.stateCd, fruit.amt, fruit.cumulativeAvg)
}
apple      0 100.0 100.0
apple      0 200.0 150.0
apple      1 100.0 150.0
apple      0 300.0 200.0
orange     0 100.0 100.0
orange     1 100.0 100.0
orange     0 400.0 250.0
0 голосов
/ 26 ноября 2018

Простой цикл for может сделать это

var sum = 0
var count = 0
for i in 0..<fruit.count
{
    if(fruit[i].stateCd == 0)
    {
        count += 1
        sum += fruit[i].amt
        fruit[i].cumulativeAvg = sum/count
    }
    else if(fruit[i].stateCd == 1)
    {
        fruit[i].cumulativeAvg = sum/count
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...