【问题标题】:How do loop through an array that contains all numbers between two integers in swift?如何快速遍历包含两个整数之间的所有数字的数组?
【发布时间】:2015-04-22 22:30:36
【问题描述】:

我想要做的是使用从startend 连续的任何整数数组运行“fizzbizz”函数,然后根据下面的每种情况输出一个对象数组,整数或字符串。

在这个例子中,我试图在一个数组上运行函数,该数组从整数 1 的 start 到整数 15 的 end

随着 fizzbuzz 函数的运行,对于该范围内的每个整数,我想检查它是否可以被 3 和/或 5 整除。如果它可以被 3 而不是 5 整除,我想返回“Fizz”,如果它不能被 3 整除,而是被 5 整除,我想返回“Buzz”,依此类推。

我无法弄清楚如何设置 numsarray 以包含函数的两个输入之间的所有数字 startend,我在下面的数组中拥有的是伪代码。当我用一组特定数字尝试它时,每个case 中的所有returns 都会给我一个错误,指出我无法将该表达式转换为[Any] 类型的表达式。

我使用[Any] 是因为我会将整数和字符串都推送到数组中,所以我不想让它成为一种特定类型。

func fizzinAndBuzzin(start: Int, end: Int) -> [Any]{

    let numsarray = [start...end]

    for number in numsarray {
        switch (number % 3 == 0, number % 5 == 0) {
        case (true, false):
            return "Fizz"
        case (false, true):
            return "Buzz"
        case (true, true):
            return "FizzBuzz"
        default:
            return int(start)
        }
    }  
}

fizzinAndBuzzin(1, 15)

【问题讨论】:

  • 遍历数组中的所有数字是没有意义的,因为无论如何你都将在循环的第一次迭代中转到return...
  • @nhgrif 这是一个很好的观点。有什么更好的方法来做到这一点?

标签: arrays swift fizzbuzz


【解决方案1】:

您的函数的返回类型是[Any],它是一个任意数组。您不是返回数组,而是返回单个对象。像这样改变你的函数定义:

func fizzinAndBuzzin(start: Int, end: Int) -> Any {

然后你的代码就没有意义了。你的目标是回归吗

[1,2,"fizz",4,"buzz","fizz",7,8,"fizz","buzz"]

等等。

如果是这样,那么您不想在每种情况下都返回,而是要构建一个数组:

func fizzinAndBuzzin(start: Int, end: Int) -> [Any]
{
    //Create an empty array of Any
    var numsArray = [Any]()

    for number in start...end 
    {
        switch (number % 3 == 0, number % 5 == 0) {
        case (true, false):
            numsArray.append("Fizz")
        case (false, true):
            numsArray.append("Buzz")
        case (true, true):
            numsArray.append("FizzBuzz")
        default:
            numsArray.append(number)
        }
    }  
    return numsArray
}

【讨论】:

    【解决方案2】:

    map 函数正是为此目的而设计的,即获取一个数组,对每个元素应用闭包,然后从中创建一个新数组。例如:

    let foo = [1, 2, 3]
    let bar = foo.map { number -> Int in
        return number * 2
    }
    

    这会将bar 分配给:

    [2, 4, 6]
    

    因此,将map 应用于您的原始问题,它看起来像:

    func fizzinAndBuzzin(start: Int, end: Int) -> [Any] {
        let numsarray = Array(start ... end)
        return numsarray.map() { number -> Any in
            switch (number % 3 == 0, number % 5 == 0) {
            case (true, false):
                return "Fizz"
            case (false, true):
                return "Buzz"
            case (true, true):
                return "FizzBuzz"
            default:
                return number
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      看来您的意图是在开始和结束之间构建一个包含“Fizz Buzz 值”的数组,包括在内。所以考虑到这一点,我们不需要创建一个let 数组,而是创建一个空的var 数组并填充它。

      我们的switch 语句应该将值加载到这个数组中。但我实际上会在这里选择一些抽象,所以首先,一个函数只接受一个 Int 并返回适当的值:

      func fizzBuzzify(value: Int) -> Any {
          switch (value % 3, value % 5) {
          case (0, 0):
              return "FizzBuzz"
          case (0, _):
              return "Fizz"
          case (_, 0):
              return "Buzz"
          default:
              return value
          }
      }
      

      现在,让我们修复 fizzinAndBuzzin 函数:

      func fizzinAndBuzzin(start: Int, end: Int) -> [Any] {
          var values = Array<Any>()
          values.reserveCapacity(end-start+1)
      
          for index in start...end {
              values.append(fizzBuzzify(index))
          }
      
          return values
      }
      

      这种方法一次性预先分配整个数组的内存(我们事先知道确切它将有多大)。与依赖 .append 的方法相比,对于非常大的 start-end 增量,这将产生非常显着的差异。

      【讨论】:

      • 我很好奇。为什么你用零预先填充数组,然后返回并在每个零上安装“fizzBu​​zzified”结果?所以你可以使用数组索引而不是array.append?如果目标是避免数组不断调整自身大小。在这种情况下,我会使用 reserveCapacity()。
      • @DuncanC 是的,这就是原因。我刚刚编辑了答案。我找不到这个的构造函数重载...没有意识到它是一个实例方法。
      • 我知道。似乎应该有一个方便的初始化器,比如 NSMutableArray 的 arrayWithCapacity。
      • 您的编辑不太正确。在swift中,您不能像在Objective-C中那样使用索引将新对象添加到数组中,并且reserveCapacity会分配存储空间,但不会用项目填充数组,因此代码可能会崩溃。如果您要切换到使用 reserveCapacity,您还必须切换到使用 values.append()。 (我编辑了你的答案。)
      • 你知道 Swift 数组是否为块中的项目分配空间吗?我希望他们这样做,因为内存分配无论如何都是以块的形式完成的。这将减少重复附加到开始为空的数组的性能损失。
      猜你喜欢
      • 1970-01-01
      • 2021-08-03
      • 2015-05-19
      • 2020-02-02
      • 1970-01-01
      • 1970-01-01
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多