【问题标题】:Averaging elements in array of arrays by index using functional programming使用函数式编程按索引平均数组中的元素
【发布时间】:2018-03-13 17:00:46
【问题描述】:

我有一个双精度数组。例如:

let mceGain = [[3,4,5],[7,4,3],[12,10,7]] // Written as integers for simplicity here

我现在想用相应的索引对不同数组中的元素进行平均。所以我的输出看起来有点像这样:

//firstAvg: (3+7+12)/3 = 7.33
//secondAvg: (4+4+10)/3 = 6
//thirdAvg: (5+3+7)/3 = 5

最后我想将这些平均值存储在一个更简单的数组中:

//mceGain: [7.33,6,5]

我尝试使用内部带有 switch 语句的双 for 循环来执行此操作,但这似乎不必要地复杂。我假设使用reduce()map()filter() 的组合可以实现相同的结果,但我似乎无法理解它。

【问题讨论】:

  • 我会将两个单独的、更简单的操作组合起来:首先转置[[3, 4, 5], [7, 4, 3], [12, 10, 7]],生成[[3, 7, 12], [4, 4, 10], [5, 3, 7]],然后用map 平均每个子数组以生成[7.33, 6, 5]

标签: arrays swift functional-programming


【解决方案1】:

这应该回答你下面的评论

let elms: [[Double]] = [[3, 5, 3], [4, 4, 10] , [5, 3, 7]]

func averageByIndex(elms:[[Double]]) -> [Double]? {
    guard let length = elms.first?.count else { return []}

    // check all the elements have the same length, otherwise returns nil
    guard !elms.contains(where:{ $0.count != length }) else { return nil }

    return (0..<length).map { index in
        let sum = elms.map { $0[index] }.reduce(0, +)
        return sum / Double(elms.count)
    }
}

if let averages = averageByIndex(elms: elms) {
    print(averages) // [4.0, 4.0, 6.666666666666667]
}

【讨论】:

  • 这给了我每个子数组的平均值。我正在寻找的是每个子数组的第 i 个元素之和的平均值。 :=)
  • 谢谢。结构非常好。
【解决方案2】:

让我们来分析一下你想在这里做什么。你从数组数组开始:

[[3,4,5],[7,4,3],[12,10,7]]

你想将每个子数组转换成一个数字:

[7,6,5]

当你遇到这种“将这个序列的每个元素转换成别的东西”的情况时,使用map

当您计算平均值时,您需要将一系列事物转换为一个事物。这意味着我们需要reduce

let array: [[Double]] = [[3,4,5],[7,4,3],[12,10,7]]
let result = array.map { $0.reduce(0.0, { $0 + $1 }) / Double($0.count) }

使用 cmets:

let array: [[Double]] = [[3,4,5],[7,4,3],[12,10,7]]
let result = array.map { // transform each element like this:
    $0.reduce(0.0, { $0 + $1 }) // sums everything in the sub array up 
    / Double($0.count) } // divide by count

编辑:

你需要做的是先“转置”数组,然后做map和reduce:

array[0].indices.map{ index in // these three lines makes the array [[3, 7, 12], [4, 4, 10], [5, 3, 7]]
    array.map{ $0[index] }
}
.map { $0.reduce(0.0, { $0 + $1 }) / Double($0.count) }

【讨论】:

  • 这给了我每个子数组的平均值。我正在寻找的是每个子数组的 ith 元素之和的平均值。不过分析得非常好!
  • @matiasofteby 已编辑。
  • 我希望我能给你们两个最好的答案。 :=)
猜你喜欢
  • 2014-04-17
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
  • 2022-01-11
  • 2019-04-14
  • 2013-12-29
  • 2019-08-28
  • 1970-01-01
相关资源
最近更新 更多