2016-01-23 60 views
0

的陣列I具有元組的數組:減少元組

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

在該陣列中可以存在2個或更多相同Item不同amount。我想減少這baseItems陣列只包含獨特的Item s和加起來amount

下面是一個例子:

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

應轉變爲:

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

回答

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)] 

這樣的事情。仍然可以做得更高雅一點。

UPDATE:

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") 
+0

謝謝你的回答。這可能是我正在尋找的。雖然我無法實現它,因爲它不是[(String,Int)]而是[(Item,Float)]。我得到的錯誤無法調用類型'Set <_>'的初始值設定項,其類型爲'([Item])'的參數列表。我設法得到一個過濾的[(id:Int,amount:Float)]數組,並且有一個方法從一個id到達適當的Item,但是我覺得這更像是一件俗事 – smnk

+0

是的,我改變了它是一個字符串,因此測試更容易。你必須改變你的類'Item'以符合'Hashable'協議,所以它可以和'Set'一起使用。看到我更新的答案。 – Eendje

0

您可以通過減少字典,關鍵是該項目,值該項目金額的總和,之後回到元組數組:

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且可用作字典的關鍵字,它就可以與任何其他類型一起使用。