【问题标题】:more elegant code for for if in swift更优雅的代码 for if in swift
【发布时间】:2016-04-07 14:16:38
【问题描述】:

我得到了一个简单的代码,它可以正常工作,并且我正在用老式的方式进行编程,我相信有一种更优雅的方式可以快速完成这项工作。代码如下:

    var cardsInCompartment1:Int = 0
    var cardsInCompartment2:Int = 0
    for card in cards{
        if card.compartment == 1{
            cardsInCompartment1 += 1
            print(cardsInCompartment1)
        }
        if card.compartment == 2{
            cardsInCompartment2 += 1
            print(cardsInCompartment2)
        }
    }

我基本上把卡片放在不同的隔间里,现在我想计算每个隔间里有多少张卡片。

【问题讨论】:

    标签: swift if-statement for-loop


    【解决方案1】:

    使用filter 选择你想要的卡片怎么样?然后你可以count他们:

    let cardsInCompartment1 = cards.filter { $0.compartment == 1 }.count
    let cardsInCompartment2 = cards.filter { $0.compartment == 2 }.count
    

    如果你有一堆隔间,你可以将计数存储在字典中:

    var compartmentCounts = [Int:Int]()
    
    cards.forEach {
        compartmentCounts[$0.compartment] = (compartmentCounts[$0.compartment] ?? 0) + 1
    }
    

    在这种情况下,键是隔间#,值是卡数。如果每个隔间分别有 32 和 42 张卡片,则类似于 [1: 32, 2: 42]

    【讨论】:

    • 这里的主要问题是您现在对列表进行了两次迭代。
    • @magni- 我不认为这是一个大问题,除非存在明显的性能问题。编译器完全有可能消除大部分低效率……对于少数卡,这并不重要。对我来说,代码可读性是第一位的。
    • @magni- 我更新了一个在一次迭代中完成的解决方案。
    • 完全同意这对于小列表并不重要,但是有一个同样 (IMO) 易于阅读的解决方案,它只在一次迭代中完成,那么为什么不一次完成呢?这样,即使我们有 20 个不同的隔间,它仍然表现良好。
    【解决方案2】:

    试试这个:

    var cardsInCompartment1:Int = 0
    var cardsInCompartment2:Int = 0
    for card in cards {
        (card.compartment == 1) ? (cardsInCompartment1 += 1) : (cardsInCompartment2 += 1)
    }
    

    【讨论】:

      【解决方案3】:

      我认为您应该将cardsInCompartment 存储为数组:

      var cardsInCompartment = [0, 0] // you can add more to this array
      

      然后您可以循环遍历 cards 并将值添加到数组元素中:

      for card in cards {
          cardsInCompartment[card.compartment - 1] += 1
          print(cardsInCompartment[card.compartment - 1])
      }
      

      【讨论】:

      • 这将为cards中的每张卡片打印
      • @nielsbot 那又怎样?从给定的上下文来看,我认为他无论如何都会打印所有卡片。
      • 很好。这就是原版所做的。似乎无意。
      【解决方案4】:

      switch 语句呢?像这样?

      var card:Int = 1
      var CardsInCompartment:Int = 0
      switch (card) {
      case 1:
        CardsInCompartment += 1
        print("CardsInCompartment \(CardsInCompartment)")
      case 2:
        CardsInCompartment += 2
        print("CardsInCompartment \(CardsInCompartment)")
      default:
      }
      

      【讨论】:

        【解决方案5】:

        或者,使用数组来保持计数:

        var counts = [ 0, 0, 0 ] // create an array of integers, where the Ints in the array represent the count of cards in each compartment
        cards.forEach { counts[ $0.compartment ] += 1 } // for each card, increment the count in array corresponding to the compartment of the card. (if card.compartment == 1, increment counts[1], and so on
        
        print("cards in compartment 1 \(counts[1])")
        print("cards in compartment 2 \(counts[2])")
        

        (假设你唯一的隔间是整数 1 和 2)

        【讨论】:

        • 这太棒了,但让我想起了我以前经常看到的 C 竞赛中的编程,这将对谁可以为给定任务创建最小、最快的代码段提出挑战。结果通常非常出色,而且非常神秘,因为很难理解它在做什么,最终在编码中需要平衡。没有不尊重 nielsbot 的意图! 12.8k 声望说明了他的能力,并且做了这两条线的守护进程。
        • 我会添加一些 cmets :)
        • 另外,我认为@Aaron Brager 的上述解决方案在相同的空间中更通用。
        【解决方案6】:

        我喜欢 Aaron Brager 将值计入字典的想法。我正在使用 reduce 来消除“循环”之外的可变字典(更实用)

        let d = cards.reduce([:]) { (d, card) -> [Int:Int] in
            var d = d
            let s = d[card.compartment] ?? 0
            d[card.compartment] = s + 1
            return d
        }
        

        【讨论】:

          猜你喜欢
          • 2016-09-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多