在 Swift 中过滤对象数组并求和它们的属性
Posted
技术标签:
【中文标题】在 Swift 中过滤对象数组并求和它们的属性【英文标题】:Filter array of objects and sum their properties in Swift 【发布时间】:2016-07-15 08:50:49 【问题描述】:我想从一系列产品中生成购物清单。 我在核心数据中有一个实体“产品”,其属性为名称(字符串)和数量(整数)。我现在有一系列产品,其中有一些重复,类似这样:
var products : [Product] = [Apple, Egg, Orange, Apple, Orange, Banana, Egg, Egg]
如何过滤此类数组以获得特定产品数量的总和?因此,我想获得数量如下的产品列表:Apple: 4, Banana: 3, Egg: 7, Orange 2
。我知道我可以从该数组中创建一个 Set 以避免重复,但在此之前我不知道如何汇总产品的数量。
【问题讨论】:
为什么你有一个带有欺骗的数组?添加到数组时为什么不合并? 【参考方案1】: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]
【讨论】:
【参考方案2】: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]
【讨论】:
【参考方案3】:你可以这样做:
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]
【讨论】:
假设您有一个包含 100 万个元素的数组,其中包含 20,000 种不同的水果。你的算法需要遍历 100 万个元素的数组多少次? 你必须有一个大家庭 7stud.... 问题是关于购物清单。 :)以上是关于在 Swift 中过滤对象数组并求和它们的属性的主要内容,如果未能解决你的问题,请参考以下文章
PHP 过滤对象数组并返回新的对象数组,同时基于一个属性删除重复项