在追加到对象中时避免乘以值

时间:2015-06-03 09:49:12

标签: swift append

我想问一下如何纠正我的问题。我只是简单地附加一些"门户网站"到一个依赖的国家。每个"门户"这不止一次,我不想追加。

我有以下类定义:

class cls_main{
    var countries:[cls_country]!

    init() {
        countries = [cls_country]()
    }

    // "add Country"
    func addCountry(iCountry:cls_country) {
        countries.append(iCountry)
    }

}

class cls_country{

    var countryName:String!
    var portals:[cls_portal]!

    init() {
        portals = [cls_portal]()
    }

    // "add Portal"
    func addPortal(portName:String) {

        var tmpPortal = cls_portal()
        tmpPortal.portalName = portName

        println("-->Input Portal: \(tmpPortal.portalName)")

        if portals.count == 0 {
            portals.append(tmpPortal)
        } else {
            for port in portals {
                if port.portalName == portName {            
                    println("SAME INPUT, DONT SAVE")  
                } else {
                    portals.append(tmpPortal)
                }
            }
        }

    }

    func arrayCount(){
        println("Portals   : \(portals.count)")
    }
}

class cls_portal{
    var portalName:String!
}

所以我会称之为:

var MAIN = cls_main()
var country = cls_country()

country.countryName = "USA"
country.addPortal("Dance")
country.addPortal("Dance") // Should not be appended...
country.addPortal("Hike")
country.addPortal("Swim")
country.addPortal("Play")

MAIN.addCountry(country)
country = cls_country()

添加值后,循环显示值并打印它们。结果是这样的:

循环:

for country in MAIN.countries {
      println("COUNTRY: \(country.countryName)")

      if country.countryName == "USA" {
        for portal in country.portals {
            println(" -> PORTAL   : \(portal.portalName)")
        }
        country.arrayCount()    
      }
} 

结果:

-->Input Portal: Dance
-->Input Portal: Dance
SAME INPUT, DONT SAVE
-->Input Portal: Hike
-->Input Portal: Swim
-->Input Portal: Play
COUNTRY: USA
 -> PORTAL   : Dance
 -> PORTAL   : Hike
 -> PORTAL   : Swim
 -> PORTAL   : Swim
 -> PORTAL   : Play
 -> PORTAL   : Play
 -> PORTAL   : Play
 -> PORTAL   : Play
Portals   : 8

那么为什么每个门户网站最终会成倍增加?非常感谢你。

3 个答案:

答案 0 :(得分:0)

在您的搜索循环中,您在查看每个元素后决定tmpPortal是否在portals中。在做出决定之前,您需要查看所有项目。添加变量found以注意已找到它。一旦找到该项目,您就可以break离开循环。

if portals.count == 0 {
    portals.append(tmpPortal)
} else {
    var found = false
    for port in portals {
        if port.portalName == portName {
            println("SAME INPUT, DONT SAVE")
            found = true
            // found it, stop searching
            break
        }
    }
    if !found {
        portals.append(tmpPortal)
    }
}

答案 1 :(得分:0)

您在阵列上多次循环,检查它。但是对于匹配的每个元素,您都要插入门户网站。所以当有其他3个不匹配的元素时,你会插入3次门户网站。

尝试使用以下内容替换内部循环(从if portals.count ==一直到else的结尾):

if !contains(portals, { $0.portalName == portName }) {
    portals.append(tmpPortal)
}

contains是一个函数,用于检查集合(如您的门户网站数组)是否包含符合特定条件的条目。标准由闭包确定,在这种情况下,闭包检查元素的门户名称是否与您要检查的门户名称匹配。如果您不熟悉闭包,请尝试阅读this link - 它们在Swift中非常有用。

P.S。您可能需要重新考虑代码中的其他一些内容。例如,最好避免使用implicitly-unwrapped optionals(即!之后的类型)。隐式选项在Swift中用于某些非常特定的目的,它看起来不适用于您的代码。特别是不使用数组 - 最好只在初始化时使数组为空。但是,如果拥有一个没有国家/地区名称的门户网站是没有意义的,那么您可以将其作为初始化程序的一部分。

所以不要这样:

class cls_country{

    var countryName:String!
    var portals:[cls_portal]!

    init() {
        portals = [cls_portal]()
    }
}

// and in use:
var tmpPortal = cls_portal()
tmpPortal.portalName = portName
你可以写下这个:

class cls_country {
    var portals = [cls_country]()
    // consider let not var if a country will never 
    // need to change its name:
    let countryName: String

    init(countryName: String) {
        self.countryName = countryName
        //no need to initialize portals in init
    }
}
// then later, in use:
var tmpPortal = cls_portal(countryName: portName)

答案 2 :(得分:0)

如果您使用的是Swift 1.2,那么使用Set可以更好地解决这个问题,因此您根本不需要使用addPortal方法。 Set提供与数组几乎相同的功能,但它根本不存储相同的值。请注意,为了使其与set一起使用,您的cls_portal类必须采用hashable和equitable协议

  

集合在集合中存储相同类型的不同值,没有定义的顺序。当项目的顺序不重要时,或者当您需要确保项目只出现一次时,您可以使用集合作为数组的替代。