簡體   English   中英

更改數組屬性時,Swift映射不起作用

[英]Swift map doesn't work when changing array property

我有以下結構,有一些屬性:

struct Partner {
    let id: Int
    let nome: String
    let icone: String
    var isSelected : Bool
}

所以我初始化一個簡單的數組並在其中放入一些數據:

var parceiros : [Partner] = [
    Partner(id: 1, nome: "Personal Profile", icone: "btPersonal",isSelected : true),
    Partner(id: 2, nome: "Professional Profile", icone: "btProfessional", isSelected: false)
]

但是當我想用高階函數Map更改“isSelected”屬性時,在swift 4中,數組根本不會更新。 它很奇怪,因為var“_parceiro”在返回循環中具有正確的值。 但是在函數之后,數組返回到原始值。

private func select(partner: Partner){
    let _ = parceiros.map { (parceiro) -> Partner in
        var _parceiro = parceiro
        _parceiro.isSelected = parceiro.id == partner.id ? true : false
        return _parceiro
    }
}

您會混淆參考和值類型。 當您使用Swift數組結構(struct是value-type)時,它們會創建您放入其中的任何內容的副本 當您從結構中檢索任何內容時,它將生成另一個副本 基本上映射創建從舊數組中獲取的新結構的新數組。 你必須分配該數組:

private func select(partner: Partner){
    parceiros = parceiros.map { (parceiro) -> Partner in
        var _parceiro = parceiro
        _parceiro.isSelected = parceiro.id == partner.id ? true : false
        return _parceiro
    }
}

或者您可以使用引用類型:class。 這意味着數組將保留對對象的實際實例的引用,而不是保留結構的副本。

class Partner {
    let id: Int
    let nome: String
    let icone: String
    var isSelected : Bool
}

並改變其中的特定對象。 但是,您不需要映射。 如果你想為每個數組成員使用forEach ,如果你想將某些東西應用到數組的一部分 - 首先使用filter

private func select(partner: Partner){
        parceiros.forEach {  $0.isSelected = (parceiro.id == partner.id) }
}

map不是一個變異函數。 它可用於迭代集合並將相同的轉換函數應用於集合的所有元素,將轉換后的值存儲在新集合中並返回該新集合。

您需要使用一個簡單的循環並手動修改原始數組中的選定值,或者只使用map的返回值。

private func select(partner: Partner) -> [Partner] {
    return parceiros.map { (parceiro) -> Partner in
        var _parceiro = parceiro
        _parceiro.isSelected = parceiro.id == partner.id
        return _parceiro
    }
}

parceiros = select(parceiros[0])

如果你想使用map方法,你也可以將閉包簡化為單行,如下所示:

private func select(partner: Partner, from partners: [Partner]) -> [Partner] {
    return partners.map { return Partner(id: $0.id, nome: $0.nome, icone: $0.icone, isSelected: $0.id == partner.id)}
}

let selectedPartners = select(partner: parceiros[1], from: parceiros)

使用常規循環的方法:

private func select(partner: Partner){
    for i in parceiros.indices {
        parceiros[i].isSelected = parceiros[i].id == partner.id
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM