【问题标题】:Get repeating values in dictionary array. Swift获取字典数组中的重复值。迅速
【发布时间】:2017-09-05 04:12:47
【问题描述】:

我有一个这样的数组

[
    ["itm_id": 4, "itm_name": Chicken],
    ["itm_id": 4, "itm_name": Chicken],
    ["itm_id": 4, "itm_name": Chicken],
    ["itm_id": 7, "itm_name": Cat]
]

我有这个字典数组,我正在尝试按字典中的值对它们进行分组。所以在我上面的例子中,我想知道创建一个字典来知道我有多少个带有重复键的字典:

[["item_id" : 4, count: 3], ["item_id" : 7, count: 1]]

itm_id: 4 重复 3 次,因此计数为 3,itm_id: 7 仅重复一次。

我怎样才能做到这一点

【问题讨论】:

  • 为您的字典定义“相等”。你只需要itm_id 匹配,还是itm_iditm_name 都匹配?如果我有["itm_id": 4, "itm_name": Duck] 怎么办?是否等于Chicken?如果你有不同的Chickens怎么办?
  • 我建议使用结构而不是字典(就像已经回答过的那样),使其符合Hashable 协议,并使用NSCountedSet 来了解对象的次数在给定的集合中重复。

标签: arrays swift swift3


【解决方案1】:

我建议你创建一个项目数组的struct,而不是像这样的字典

struct Item{
    var itemID : Int
    var name : String

    init(dictionary:[String:Any]) {
        itemID = dictionary["itm_id"] as? Int ?? 0
        name = dictionary["itm_name"] as? String ?? ""
    }
}

一旦您拥有Items 的数组,您就可以将特定项目 ID 的元素映射为数组,以获取计数并将它们从数组中删除。看看下面的代码。不是最干净的实现,但它可以帮助您解决问题。

func countDuplicates(){
    let dictionary = [["itm_id": 4, "itm_name": "Chicken"],["itm_id": 4, "itm_name": "Chicken"],["itm_id": 4, "itm_name": "Chicken"],["itm_id": 7, "itm_name": "Cat"]]
    var items = [Item]()
    var countArray = [[String:Any]]()
    dictionary.forEach{
        items.append(Item(dictionary: $0))
    }
    while items.count > 0 {
        if let firstItem = items.first{
            let duplicateItems = items.filter{$0.itemID == firstItem.itemID}
            var countDictionary = [String:Any]()
            countDictionary["itm_id"] = firstItem.itemID
            countDictionary["count"] = duplicateItems.count
            countArray.append(countDictionary)
            items = items.filter{$0.itemID != firstItem.itemID}
        }
    }
    print(countArray)
}

这将打印[["itm_id": 4, "count": 3], ["itm_id": 7, "count": 1]]

我假设ChickenCat 是字符串。如果它们不是字符串而是类类型,您可以将 Item 结构重写为类似这样的内容

class Animal{}

class Chicken:Animal{}

class Cat:Animal{}

struct Item<T:Animal>{
    var itemID : Int
    var name : String
    var animal : Animal

    init(dictionary:[String:Any],animal:T) {
        itemID = dictionary["itm_id"] as? Int ?? 0
        name = dictionary["itm_name"] as? String ?? ""
        self.animal = animal
    }
}

然后就可以像这样初始化Item了

yourItem = Item(dictionary:yourDictionary,animal:Cat())

【讨论】:

  • 不要将属性声明为隐式展开的可选属性,这些属性在 init 方法中使用非可选值初始化。永远不要那样做。去掉感叹号。
【解决方案2】:

// 斯威夫特 3.1

选项 1:使用字典

func countRepeats() -> [[String: Int]] {
    var repeats = [Int: Int]()
    arr.forEach { item in
        if let id = item["itm_id"] as? Int {
            repeats[id] = repeats[id] == nil ? 1 : repeats[id]! + 1
        }
    }
    return repeats.map {["item_id" : $0.key, "count": $0.value]}
}

print(countRepeats()) // [["item_id": 4, "count": 3], ["item_id": 7, "count": 1]]

选项2:建议使用Struct而不是Dictionary

public struct ItemCount {
    let id: Int
    let count: Int
}

func countRepeats() -> [ItemCount] {
    var repeats = [Int: Int]()
    arr.forEach { item in
        if let id = item["itm_id"] as? Int {
            repeats[id] = repeats[id] == nil ? 1 : repeats[id]! + 1
        }
    }
    return repeats.map {ItemCount(id:$0.key, count: $0.value)}
}

print(countRepeats())

【讨论】:

    【解决方案3】:

    我建议在类(或结构)中处理您的数据,但如果您必须使用字典数组,这是获取计数的一种方法:

    // extract all the "itm_id" values from all dictionaries in the array
    // use a set to identify unique values
    // map each unique values to its count in the array
    
    let ids = dictionaries.flatMap{$0["itm_id"] as? Int}
    let idCounts = Set(ids).map{ id in (id, ids.filter{$0==id}.count) }
    
    // You can use map() to turn this into yet another array of dictionaries
    
    let idCountDict = idCounts.map{["itm_id":$0 ,"count":$1]}
    
    print(idCounts)     // [(4, 3), (7, 1)]
    print(idCountDict)  // [["itm_id": 4, "count": 3], ["itm_id": 7, "count": 1]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-05
      • 1970-01-01
      • 2021-10-26
      • 2019-09-21
      • 2021-07-01
      • 1970-01-01
      相关资源
      最近更新 更多