减少元组数组

时间:2016-01-23 10:24:50

标签: ios arrays swift mapreduce

我有一组元组:

var baseItems = [(item: Item, amount: Float)]

在此数组中,可能有两个或多个相同的Item具有不同的amount。我想将此baseItems数组缩小为仅包含唯一的Item并添加amount

以下是一个例子:

baseItems = [(Wood, amount: 10), (Metal, amount: 5), (Wood, amount: 3)]

应转换为:

baseItems = [(Wood, amount: 13), (Metal, amount: 5)]

2 个答案:

答案 0 :(得分:1)

let baseItems = [(wood, amount: 10), (metal, amount: 5), (wood, amount: 3)]
var newArray: [(Item, Float)] = []

// One line
Set(baseItems.map { $0.0 }).forEach { base in newArray += [(base, baseItems.filter { $0.0 == base }.reduce(0) { $0 + Float($1.1) })] }

print(newArray) // [(Wood, amount: 13), (Metal, amount: 5)]

像这样的东西。仍然会变得更优雅。

更新:

class Item: Hashable {
    let name: String

    init(name: String) {
        self.name = name
    }

    var hashValue: Int { return name.hashValue }
}

func ==(lhs: Item, rhs: Item) -> Bool {
    return lhs.name == rhs.name
}

let woods = Item(name: "Woods")
let metal = Item(name: "Metal")

答案 1 :(得分:0)

您可以使用key作为项目来减少字典,并为该项目的值总和值,然后返回到元组数组:

let baseItems = [(item: "Wood", amount: 10), (item: "Metal", amount: 5), (item: "Wood", amount: 3)]
let normalizedItems = baseItems.reduce([String:Int]()) {
    var dict = $0
    dict[$1.item] = (dict[$1.item] ?? 0) + $1.amount
    return dict
    }.map{$0}

或者,在一行中:

let normalizedItems = baseItems.reduce([String:Int]()) { var d = $0; d[$1.item] = (d[$1.item] ?? 0) + $1.amount; return d }.map{$0}

注意。我认为该项目是String,金额是Int,但这适用于任何其他类型,只要该项目是Hashable并且可以用作词典的键。