2016-12-12 40 views
1
var allEvents: [String] = ["SOUTHERN STATES PASS LAWS TO DISENFRANCISE BLACKS", "THEODORE ROOSEVELT ELECTED VICE PRESIDENT", "WRIGHT BROTHERS FIRST FLIGHT", "SAN FRANCISCO EARTHQUAKE", "FORD INTRODUCES MODEL T", "WORLD WAR I BEGINS IN EUROPE", "WORLD WAR I ENDS", "TR DIES – CARNEGIE DIES", "GERMAN MONEY HYPER INFLATES", "TREATY OF VERSAILLES, 19TH AMENDMENT", "HINDENBURG ELECTED PRESIDENT OF GERMANY", "STOCK MARKET CRASHES, DEPRESSION BEGINS", "HITLER’S NAZI PARTY GAINS MAJORITY IN PARLIAMENT", "HITLER BEGINS TO TAKE POWER IN GERMANY", "FRANKLIN ROOSEVELT ELECTED PRESIDENT", "FDR INAUGURATED “100 DAYS”", "HINDENBURG DIES, HITLER APPOINTS HIMSELF PRESIDENT - “ FUEHRER”", "FDR RE-ELECTED", "German airship HINDENBURG BURNS IN NEW JERSEY", "“MUNICH” – British P.M. Chamberlain agrees that Hitler can have Czechoslovakia.", "Germany invades Holland, Belgium and France – Churchill becomes P.M.", "Germany invades Russia", "JAPANESE ATTACK PEARL HARBOR – U.S. DECLARES WAR ON JAPAN", "HITLER DECLARES WAR ON U.S."] 

var eventIndex1: Int = 0 
var eventIndex2: Int = 0 
var eventIndex3: Int = 0 
var eventIndex4: Int = 0 

func generateRandomIndex() -> [Int] { 
    while (eventIndex1 == eventIndex2) && (eventIndex2 == eventIndex3) && (eventIndex1 == eventIndex3) && (eventIndex1 == eventIndex4) && (eventIndex2 == eventIndex4) && (eventIndex3 == eventIndex4) { 
     eventIndex1 = GKRandomSource.sharedRandom().nextInt(upperBound: allEvents.count) 
     eventIndex2 = GKRandomSource.sharedRandom().nextInt(upperBound: allEvents.count) 
     eventIndex3 = GKRandomSource.sharedRandom().nextInt(upperBound: allEvents.count) 
     eventIndex4 = GKRandomSource.sharedRandom().nextInt(upperBound: allEvents.count) 
    } 
    return [eventIndex1, eventIndex2, eventIndex3, eventIndex4] 
} 

var eventIndexes = generateRandomIndex() 
var index1 = eventIndexes[0] 
var index2 = eventIndexes[1] 
var index3 = eventIndexes[2] 
var index4 = eventIndexes[3] 
var event1 = allEvents[index1] 
var event2 = allEvents[index2] 
var event3 = allEvents[index3] 
var event4 = allEvents[index4] 

上面的代码基本上使用函数应该生成的不重复的随机索引从allEvents数组中抽取。除了每个事件变量,还有一个'不能在属性初始值设定项中使用实例成员'allEvents';属性初始值设定项在“自我”可用之前运行。有什么建议么?不知道如何解决。'不能在属性初始值设定项中使用实例成员'allEvents';属性初始值设定项在'self'可用之前运行'错误

+0

您的'generateRandomIndex()'函数不会做你认为它的功能。它不保证缺少重复项(当你的意思是'||'时,你使用'&&')。做你想做什么的标准方式叫做洗牌。查看http://stackoverflow.com/questions/24026510/how-do-i-shuffle-an-array-in-swift –

+2

你的陈述“全球范围”混淆了埃里克(你不是指“全球范围”,你的意思这些是ViewController的属性)。 –

+0

@RobNapier,我对代码有点新,所以我不太了解用来创建一个shuffle方法的语法。如果我可以使用更多的基本语法来表达我的逻辑,那将更加简单。那么使用&&有什么错误? while循环持续生成随机数,直到ALL(因此,&&)事件索引彼此不相同。使用||会破坏这个逻辑。 –

回答

1

您无法使用其他属性的值初始化标准属性(并且没有承诺它们将按照您认为的原则按源代码顺序初始化)。您可以使用另一个的值来初始化lazy属性,但这对于此问题太复杂了。访问对象的属性需要初始化整个对象,并且在设置所有属性之前不会初始化它。

这种逻辑最好在init中完成。这是我会怎么写我自己(与shuffle extension):

class ViewController { 
    //There's just one of these in the world, not one per class. And I can't 
    // imagine it changing (so should be let) 
    static let allEvents = ["SOUTHERN STATES PASS LAWS TO DISENFRANCISE BLACKS", "THEODORE ROOSEVELT ELECTED VICE PRESIDENT", "WRIGHT BROTHERS FIRST FLIGHT", "SAN FRANCISCO EARTHQUAKE", "FORD INTRODUCES MODEL T", "WORLD WAR I BEGINS IN EUROPE", "WORLD WAR I ENDS", "TR DIES – CARNEGIE DIES", "GERMAN MONEY HYPER INFLATES", "TREATY OF VERSAILLES, 19TH AMENDMENT", "HINDENBURG ELECTED PRESIDENT OF GERMANY", "STOCK MARKET CRASHES, DEPRESSION BEGINS", "HITLER’S NAZI PARTY GAINS MAJORITY IN PARLIAMENT", "HITLER BEGINS TO TAKE POWER IN GERMANY", "FRANKLIN ROOSEVELT ELECTED PRESIDENT", "FDR INAUGURATED “100 DAYS”", "HINDENBURG DIES, HITLER APPOINTS HIMSELF PRESIDENT - “ FUEHRER”", "FDR RE-ELECTED", "German airship HINDENBURG BURNS IN NEW JERSEY", "“MUNICH” – British P.M. Chamberlain agrees that Hitler can have Czechoslovakia.", "Germany invades Holland, Belgium and France – Churchill becomes P.M.", "Germany invades Russia", "JAPANESE ATTACK PEARL HARBOR – U.S. DECLARES WAR ON JAPAN", "HITLER DECLARES WAR ON U.S."] 

    // Do you really need both of these? If so, I'd probably actually just keep 
    // eventIndices and compute events when needed, but if you access it a lot, 
    // this is fine. But "event1" "event2" etc is bad practice 
    let eventIndices: [Int] 
    let events: [String] 

    init() { 
     eventIndices = Array(ViewController.allEvents.indices.shuffled().prefix(4)) 
     events = eventIndices.map { ViewController.allEvents[$0] } 
    } 
} 

OK,这就是我会做,但如果我们想保持它在你的风格,我们仍然可以做到这一点。不过,您仍然需要allEventsstatic

class ViewController { 

    static let allEvents: [String] = ["SOUTHERN STATES PASS LAWS TO DISENFRANCISE BLACKS", "THEODORE ROOSEVELT ELECTED VICE PRESIDENT", "WRIGHT BROTHERS FIRST FLIGHT", "SAN FRANCISCO EARTHQUAKE", "FORD INTRODUCES MODEL T", "WORLD WAR I BEGINS IN EUROPE", "WORLD WAR I ENDS", "TR DIES – CARNEGIE DIES", "GERMAN MONEY HYPER INFLATES", "TREATY OF VERSAILLES, 19TH AMENDMENT", "HINDENBURG ELECTED PRESIDENT OF GERMANY", "STOCK MARKET CRASHES, DEPRESSION BEGINS", "HITLER’S NAZI PARTY GAINS MAJORITY IN PARLIAMENT", "HITLER BEGINS TO TAKE POWER IN GERMANY", "FRANKLIN ROOSEVELT ELECTED PRESIDENT", "FDR INAUGURATED “100 DAYS”", "HINDENBURG DIES, HITLER APPOINTS HIMSELF PRESIDENT - “ FUEHRER”", "FDR RE-ELECTED", "German airship HINDENBURG BURNS IN NEW JERSEY", "“MUNICH” – British P.M. Chamberlain agrees that Hitler can have Czechoslovakia.", "Germany invades Holland, Belgium and France – Churchill becomes P.M.", "Germany invades Russia", "JAPANESE ATTACK PEARL HARBOR – U.S. DECLARES WAR ON JAPAN", "HITLER DECLARES WAR ON U.S."] 

    static func generateRandomIndex() -> [Int] { 
     var eventIndex1: Int = 0 
     var eventIndex2: Int = 0 
     var eventIndex3: Int = 0 
     var eventIndex4: Int = 0 

     while (eventIndex1 == eventIndex2) || (eventIndex2 == eventIndex3) || (eventIndex1 == eventIndex3) || (eventIndex1 == eventIndex4) || (eventIndex2 == eventIndex4) || (eventIndex3 == eventIndex4) { 
      eventIndex1 = GKRandomSource.sharedRandom().nextInt(upperBound: allEvents.count) 
      eventIndex2 = GKRandomSource.sharedRandom().nextInt(upperBound: allEvents.count) 
      eventIndex3 = GKRandomSource.sharedRandom().nextInt(upperBound: allEvents.count) 
      eventIndex4 = GKRandomSource.sharedRandom().nextInt(upperBound: allEvents.count) 
     } 
     return [eventIndex1, eventIndex2, eventIndex3, eventIndex4] 
    } 

    let index1: Int 
    let index2: Int 
    let index3: Int 
    let index4: Int 

    let event1: String 
    let event2: String 
    let event3: String 
    let event4: String 

    init() { 
     let eventIndexes = ViewController.generateRandomIndex() 
     index1 = eventIndexes[0] 
     index2 = eventIndexes[1] 
     index3 = eventIndexes[2] 
     index4 = eventIndexes[3] 
     event1 = ViewController.allEvents[index1] 
     event2 = ViewController.allEvents[index2] 
     event3 = ViewController.allEvents[index3] 
     event4 = ViewController.allEvents[index4] 
    } 
} 

如果allEvents不需要此文件以外的地方看到的,你可以把它简单的通过提升到文件范围:

fileprivate let allEvents: [String] = ["SOUTHERN STATES PASS LAWS TO DISENFRANCISE BLACKS", "THEODORE ROOSEVELT ELECTED VICE PRESIDENT", "WRIGHT BROTHERS FIRST FLIGHT", "SAN FRANCISCO EARTHQUAKE", "FORD INTRODUCES MODEL T", "WORLD WAR I BEGINS IN EUROPE", "WORLD WAR I ENDS", "TR DIES – CARNEGIE DIES", "GERMAN MONEY HYPER INFLATES", "TREATY OF VERSAILLES, 19TH AMENDMENT", "HINDENBURG ELECTED PRESIDENT OF GERMANY", "STOCK MARKET CRASHES, DEPRESSION BEGINS", "HITLER’S NAZI PARTY GAINS MAJORITY IN PARLIAMENT", "HITLER BEGINS TO TAKE POWER IN GERMANY", "FRANKLIN ROOSEVELT ELECTED PRESIDENT", "FDR INAUGURATED “100 DAYS”", "HINDENBURG DIES, HITLER APPOINTS HIMSELF PRESIDENT - “ FUEHRER”", "FDR RE-ELECTED", "German airship HINDENBURG BURNS IN NEW JERSEY", "“MUNICH” – British P.M. Chamberlain agrees that Hitler can have Czechoslovakia.", "Germany invades Holland, Belgium and France – Churchill becomes P.M.", "Germany invades Russia", "JAPANESE ATTACK PEARL HARBOR – U.S. DECLARES WAR ON JAPAN", "HITLER DECLARES WAR ON U.S."] 

class ViewController { 
    ... 
     event1 = allEvents[index1] 
     event2 = allEvents[index2] 
     event3 = allEvents[index3] 
     event4 = allEvents[index4] 
    ... 

但在这一切的关键教训是,你可以在对象初始化之前,不访问对象中的属性。

相关问题