2016-07-15 64 views
2

我想从一系列产品中生成购物清单。 我有一个核心数据中的实体“产品”具有名称(String)和金额(Int)作为其属性。我在那一刻,我有一系列的产品有一些重复,这样的事情:在Swift中过滤对象数组并将其属性相加

var products : [Product] = [Apple, Egg, Orange, Apple, Orange, Banana, Egg, Egg] 

如何过滤这样的阵列来获得特定产品的量的总和?我想要得到如下产品的清单:Apple: 4, Banana: 3, Egg: 7, Orange 2。我知道我可以从该数组中创建一个Set来避免重复,但我不知道如何在此之前对产品的数量进行总结。

+1

为什么你有愚弄的阵列?为什么当你添加到数组中时你不合并? – Wain

回答

3
enum Product { 
    case Apple 
    case Egg 
    case Orange 
    case Banana 
} 

let products: [Product] = [.Apple, .Egg, .Orange, .Apple, .Orange, .Banana, .Egg, .Egg] 

products.reduce([:]) { (map, product) -> [Product: Int] in 
    var updatedMap = map 
    if let value = map[product] { 
     updatedMap[product] = value + 1 
    } 
    else { 
     updatedMap[product] = 1 
    } 
    return updatedMap 
} //[Orange: 2, Apple: 2, Egg: 3, Banana: 1] 

一样用绳子:

let products: [String] = ["Apple", "Egg", "Orange", "Apple", "Orange", "Banana", "Egg", "Egg"] 

products.reduce([:]) { (map, product) -> [String: Int] in 
    var updatedMap = map 
    if let value = map[product] { 
     updatedMap[product] = value + 1 
    } 
    else { 
     updatedMap[product] = 1 
    } 
    return updatedMap 
} // ["Apple": 2, "Egg": 3, "Orange": 2, "Banana": 1] 

或者通过扩展为所有哈希的序列类型:

extension SequenceType where Generator.Element: Hashable { 
    func countElements() -> [Generator.Element : Int] { 
     return reduce([:]) { (map, element) -> [Generator.Element : Int] in 
      var updatedMap = map 
      if let value = map[element] { 
       updatedMap[element] = value + 1 
      } 
      else { 
       updatedMap[element] = 1 
      } 
      return updatedMap 
     } 
    } 
} 

products.countElements() //["Apple": 2, "Egg": 3, "Orange": 2, "Banana": 1] 
-1

你可以这样做:

enum Fruit { 
    case Orange 
    case Lemon 
    case Potato 
} 

let fruits = [Fruit.Orange, .Lemon, .Potato, .Orange, .Lemon, .Orange] 
let fruitSet = Set(fruits) 
var result = [Fruit: Int]() 

for fruit in fruitSet { 
    result[fruit] = fruits.filter { $0 == fruit }.count 
} 

有人请解释为什么我的回答没有用? 输出将是[Fruit.Orange:3,Fruit.Lemon:2,Fruit.Potato:1]

+1

假设您有一个包含20000种不同水果的100万个元素的数组。您的算法需要多少次遍历100万个元素数组? – 7stud

+0

你必须有一个大家庭7stud ....问题是关于一个购物清单。 :) – GOR

0
enum Fruit { 
    case Orange 
    case Lemon 
    case Potato 
} 

let fruits = [Fruit.Orange, .Lemon, .Potato, .Orange, .Lemon, .Orange] 

var result: [Fruit: Int] = [:] 

for fruit in fruits { 
    if let count = result[fruit] { 
     result[fruit] = count + 1 
    } 
    else { 
     result[fruit] = 1 
    } 
} 

print(result) 

--output:-- 
[Fruit.Potato: 1, Fruit.Orange: 3, Fruit.Lemon: 2] 

或者,甚至:

num Product { 
    case Apple 
    case Egg 
    case Orange 
    case Banana 
} 

let products: [Product] = [.Apple, .Egg, .Orange, .Apple, .Orange, .Banana, .Egg, .Egg] 

let result = products.reduce([:]) { (var map, product) -> [Product: Int] in 
    if let count = map[product] { 
     map[product] = count + 1 
    } 
    else { 
     map[product] = 1 
    } 

    return map 
} 

print(result) 

--output:-- 
[Product.Orange: 2, Product.Apple: 2, Product.Egg: 3, Product.Banana: 1] 
相关问题