【问题标题】:Counting number of elements in an array of array of struct in Swift 5在Swift 5中计算结构数组中的元素数
【发布时间】:2020-11-19 07:05:35
【问题描述】:

作为新手,我真的很努力解决如何解决在结构数组的数组中计算元素的问题。我尝试了几种不同的方法,但都没有得到我需要的结果。

所以我有一个名为 Card 的结构,定义如下:

 struct Card: Hashable {
    
    var dateGroup: DateGroup
    var countryGroup: CountryGroup
    var icon1: IconGroup
    var icon2: IconGroup
    
    init(dateGroup: DateGroup, countryGroup: CountryGroup, icon1: IconGroup, icon2: IconGroup) {
        
        self.dateGroup = dateGroup
        self.countryGroup = countryGroup
        self.icon1 = icon1
        self.icon2 = icon2
   
    } 
}

作为参考,Card 的元素使用以下代码定义为枚举:

enum DateGroup: String {
    
    case DG1, DG2, DG3
    
    static let allValues = [DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG1,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG2,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3, DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3,    DG3]
    
}

enum CountryGroup: String {
    
    case IT, NE, FS, US
    
    static let allValues = [IT,    IT,    IT,    IT,    IT,    IT,    IT,    IT,    NE,     NE,     IT,    NE,     NE,     NE,     IT,    IT,    IT,    NE,     IT,    NE,     IT,    IT,    IT,    NE,     IT,    IT,    IT,    IT,    NE,     IT,    NE,     NE,     FS,    FS,    NE,     IT,    IT,    NE,     NE,     IT,    IT,    NE,     FS,    FS,    FS,    NE,     FS,    NE,     NE,     NE,     NE,     FS,    NE,     NE,     FS,    NE,     IT,    NE,     NE,     FS,    FS,    NE,     IT,    NE,     FS,    NE,     NE,     NE,     NE,     FS,    FS,    FS,    FS,    FS,    US,    FS,    FS,    FS,    FS,    NE,     FS,    FS,    FS,    NE,     US,    IT]
    
}

enum IconGroup: String {
    
    case Portrait, People, Still, Scape, Setting
    
    static let allValues1 = [Portrait,     People,    People,    Portrait,     Portrait,     People,    People,    People,    People,    Portrait,     People,    Portrait,     People,    People,    People,    Portrait,     People,    Portrait,     People,    Portrait,     Portrait,     People,    People,    Portrait,     People,    People,    Portrait,     People,    Portrait,     People,    Portrait,     People,    Portrait,     People,    People,    People,    People,    Still,    People,    Portrait,     People,    Portrait,     Still,    People,    People,    People,    Portrait,     Still,    People,    Portrait,     Portrait,     People,    Still,    Still,    People,    Still,    People,    Portrait,     Portrait,     People,    People,    People,    People,    Portrait,     Portrait,     People,    Scape,    Scape,    Setting,    People,    People,    Still,    People,    Still,    Setting,    Scape,    People,    People,    People,    Still,    Still,    Portrait,     People,    Portrait,     People,    People]
    
    static let allValues2 = [Setting,    Setting,    Setting,    Setting,    Setting,    Setting,    Setting,    Scape,    Setting,    Setting,    Scape,    Scape,    Setting,    Setting,    Scape,    Scape,    Setting,    Scape,    Setting,    Scape,    Scape,    Scape,    Scape,    Setting,    Scape,    Scape,    Setting,    Scape,    Setting,    Setting,    Portrait,     Setting,    Setting,    Setting,    Scape,    Portrait,     Setting,    Still,    Scape,    Setting,    Scape,    Setting,    Still,    Scape,    Scape,    Scape,    Setting,    Still,    Scape,    Portrait,     Setting,    Setting,    Still,    Still,    Scape,    Still,    Scape,    Portrait,     Scape,    Setting,    Scape,    Setting,    Scape,    Setting,    Setting,    Scape,    Scape,    Scape,    Scape,    Scape,    Scape,    Still,    Scape,    Still,    Still,    Scape,    Setting,    Setting,    Scape,    Still,    Still,    Setting,    Setting,    Setting,    Setting,    Setting]
    
}

我创建了一个名为 DeckOfCards 的类和函数来洗牌并向定义数量的玩家发牌。我最终完成了所有工作,并通过在控制台中打印结果进行了检查,所有这些都检查出来了。

所以每个玩家有 10 张牌,并被定义为一个 Card 类型的数组(顺便说一句,玩家也存储在一个名为 newGame 的数组中)。所以 newGame[0] 是玩家 1 并且 newGame[0][0] 是玩家手中的第一张牌。因此,例如,我可以通过 newgame[0][0].dateGroup 引用该卡的 dateGroup。

我想要实现的是检查玩家是否有一组 5 张或更多卡片,其中两个卡片元素相同。我首先尝试计算玩家手中的卡片元素。例如,卡片中有多少有 DG1 的 dateGroup,有多少是 DG2 等,有多少是 countryGroup IT 等等。

我尝试使用joined(),然后进行计数,但没有奏效。我正在考虑返回一个数组,其中包含每种可能的元素类型的计数,并从这个非常骨架的代码开始:

  func createIconCount(playerHand: [Card] ) -> [String : Int] {
        
        var counts: [String: Int] = [:]

        //insert counting code here

        return counts
    }

所以我会得到一个数组,比如 [DG1: 3, DG2: 3, .... IT: 4, NE: 5, .... Portrait: 6, People: 4, .....]

帮助!有什么想法吗?

罗伯

【问题讨论】:

  • 澄清一下,如果玩家有 3 张牌,分别是 (DG1, IT)、(DG1, NE) 和 (DG2, IT),那么匹配的牌数(2 个元素相同)为零? (为简洁起见,我跳过了图标组)。 icon1 和 icon2 也是分开比较的,也就是说,如果一个玩家有 2 张牌,其中 icon1 = 人,另一张牌 icon2 = 人,那么这是匹配还是不同牌的 icon1 = icon1?跨度>
  • 嗨,我想我现在有一个解决方案。您的解释是正确的 - 您的示例中没有匹配对。我为每个图标创建了一个索引数组,然后可以查看两个索引是否相同,然后这两张卡有一对匹配。因此,如果我将这两个数组取回 [0, 2,3, 6, 7, 8] 和 [0, 1, 2, 3, 6, 7] 那么我有 5 张带有匹配对的卡片(或根据我的游戏规则)。谢谢。现在只需要编写逻辑来比较数组并声明玩家是否有集合 - 目前我只是输出数组并查看它们。

标签: arrays swift counting


【解决方案1】:

在字典查找中使用属性的rawValuedefault 总计0 来总计值:

func createIconCount(playerHand: [Card] ) -> [String : Int] {
    
    var counts: [String: Int] = [:]

    for card in playerHand {
        counts[card.dateGroup.rawValue, default: 0] += 1
        counts[card.countryGroup.rawValue, default: 0] += 1
        counts[card.icon1.rawValue, default: 0] += 1
        // Don't count icon2 if it is the same as icon1
        if card.icon2 != card.icon1 {
            counts[card.icon2.rawValue, default: 0] += 1
        }
    }

    return counts
}

创建带有图标的卡片索引数组:

您可以创建玩家手中牌的索引数组,而不是创建具有匹配图标的牌数。首先将.enumerated 添加到playerHand 以获取索引,然后将idx 附加到数组中。在这里,我们使用[] 作为默认字典查找值,如果不存在则创建一个空数组。

func createIconCount(playerHand: [Card] ) -> [String : [Int]] {
    
    var counts: [String: [Int]] = [:]

    for (idx, card) in playerHand.enumerated() {
        counts[card.dateGroup.rawValue, default: []].append(idx)
        counts[card.countryGroup.rawValue, default: []].append(idx)
        counts[card.icon1.rawValue, default: []].append(idx)
        // Don't count icon2 if it is the same as icon1
        if card.icon2 != card.icon1 {
            counts[card.icon2.rawValue, default: []].append(idx)
        }
    }

    return counts
}

【讨论】:

  • 一张卡片可以为icon1icon2 设置相同的值吗?例如,一张卡片可以是(DG1, IT, Portrait, Portrait)吗?如果是这样,您希望如何为该卡计算Portrait?一次还是两次?
  • 您好,图标 1 和图标 2 可以相同。在这种情况下,它将被视为一个图标 - 它必须与另一张卡片上的图标相匹配,例如可以是纵向和设置。
  • 嗨,顺便说一句,返回一个数组(或可能的数组数组?)显示每个计数项目的索引有多容易,例如如果 DG1 在 playerHand 中出现 4 次并且出现在 [0, 3, 4, 7]?提前致谢。罗伯
  • 您好,刚刚尝试了索引代码,效果非常好!太优雅了,谢谢。我没有意识到你可以用两位做一个 for 循环(即 for (idx, card) in )——这真的很有用而且很有帮助。我的尝试会更加笨拙!
【解决方案2】:

这是您要查找的功能:

func createIconCount(playerHand: [Card] ) -> [String : Int] {
    
    var counts: [String: Int] = [:]

    //insert counting code here
    //=========================
    for player in playerHand {
        if(!counts.keys.contains(player.dateGroup.rawValue)) {
            counts[player.dateGroup.rawValue] = 0;
        }
        counts[player.dateGroup.rawValue]! += 1;
    }
    //=========================

    return counts
}

【讨论】:

  • 谢谢你们 - 我以前没有遇到过 rawValue。
  • 嗨,两种解决方案都试过了。不幸的是,第二个返回“'Card'类型的值没有成员'rawValue'”,但第一个解决方案给了我一个包含计数的数组。感谢您的帮助 - 每天都在学习新东西!
猜你喜欢
  • 2017-06-12
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
  • 2011-06-21
  • 2017-07-15
相关资源
最近更新 更多