Swift可变数组参数

时间:2018-01-22 04:27:17

标签: swift swift4 mutability

所以我基本上试图改变一个元组变量的参数,我的代码看起来像这样:

var tabsections: [(sectionTitle: String?, rows: [String])]
tabsections = [("2017", []),
               ("2018", [])]

var mutableMonths = ["2017-02", "2017-10", "2018-01"]

for section in tabsections {
    for month in mutableMonths {
        if section.sectionTitle == month.split(separator: "-").first?.string {
            section.rows.append((month.split(separator: "-").last?.string)!)  // "Cannot use mutating member on immutable value of type '[String]'"
            mutableMonths.removeFirst()
        }
    }
}

但我一直在收到错误

  

不能对类型为'[String]'

的不可变值使用变异成员

然后在指定更多section变量,同时通过将(sectionTitle, rows)替换为循环来声明循环后,错误会变为:

  

不能在不可变值上使用变异成员:'rows'是'let'常量

我找到了关于可变性的答案,例如这个,但仅针对函数(添加关键字inout会修复它)但作为局部变量,我的想法已经用完了。

我在这里错过了一些微不足道的事情吗?

非常感谢任何帮助......

修改

我忘了提到我知道一个基于C的循环可以解决这个问题,比如

var i = 0
while i < tabsections.count {
    for month in mutableMonths {
        if tabsections[i].sectionTitle == month.split(separator: "-").first?.string {
            tabsections[i].rows.append((month.split(separator: "-").last?.string)!)
            mutableMonths.removeFirst()
        }
    }
    i += 1
}

但是我想知道在Swift 4中是否有更优雅/更好的方式这样做,因为在Swift 3中添加var就可以了。

谢谢!

3 个答案:

答案 0 :(得分:0)

你是对的。它可变。但是当您迭代tabsections时,for循环中的section无法更改。 如果你写的东西(在for循环之前)

tabsections[0].rows.append("2017-02")

它会起作用。

但是在for循环中尝试更改正在迭代的数组成员可能会导致问题。想想你是否正在开发编程语言。它有助于学习。如果有人在数组上进行迭代并从同一个数组中删除一个元素。程序状态如何?这就像切割你自己所坐的树枝。 :)

答案 1 :(得分:0)

sectionlet属性,属于for循环范围的本地属性。您可以尝试使用for var section in ...,但您仍然会制作本地副本(数组是值类型),这需要您将其重新分配回tabsections的正确索引才能更改数据。

相反,我建议你采用更实用的方法:

func parse(dateString: String) -> (year: Int, month: Int) {
    let parts = dateString.split(separator: "-")
    return (year: Int(parts[0])!, month: Int(parts[1])!)
}

var mutableMonths = ["2017-02", "2017-10", "2018-01"]
let yearMonthPairs = mutableMonths.map(parse(dateString:))

let tabSections = Dictionary(grouping: yearMonthPairs, by: { $0.year })
    .mapValues{ $0.map{ $0.month } }

这会生成一个类型为[Int: [Int]]的字典,在这些年内映射数年到数月,全部为Int,因此它们更容易使用。当您需要将其显示为表格时,您只需在其上调用.map{ year, months in (section: String(year), row: months.map(String.init)) },它将生成与您的初始代码使用的元组相同的元组

答案 2 :(得分:0)

错误背后的原因是,在迭代你的第一个for循环时,&#39;部分&#39;变量是let type.So,解决方案是:

var tabsections: [(sectionTitle: String?, rows: [String])] = []
tabsections = [("2017", []),
           ("2018", [])]

var mutableMonths = ["2017-02", "2017-10", "2018-01"]

for (index,section) in tabsections.enumerated() {
for month in mutableMonths {
if section.sectionTitle == month.split(separator: "-").first?.string {
        tabsections[index].rows.append((month.split(separator: "-").last?.string)!)  // "getting error as section is let type variable"
        mutableMonths.removeFirst()
  }
 }
}