2016-12-12 3 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 »в инициализаторах свойств; Инициализаторы свойств запускаются до того, как «self» доступен ». Какие-либо предложения? Не знаю, как исправить.«Невозможно использовать экземпляр« allEvents »в инициализаторах свойств; Инициализаторы свойств запускаются до того, как «self» доступен »Ошибка

+0

Функция 'generateRandomIndex()' не делает то, что вы думаете. Он не обещает отсутствие дубликатов (вы использовали '&&', когда вы имели в виду '||'). Стандартный способ делать то, что вы пытаетесь сделать, называется перетасовкой. См. Http://stackoverflow.com/questions/24026510/how-do-i-shuffle-an-array-in-swift –

+2

Ваше утверждение «глобальный охват» смутило Эрика (вы не имели в виду «глобальный охват», вы имели в виду что это свойства ViewController). –

+0

@RobNapier, я немного новичок в коде, поэтому я не совсем понимаю синтаксис, используемый для создания метода тасования. Было бы намного проще, если бы я мог использовать более простой синтаксис для передачи моей логики. Итак, что случилось с использованием &&? Цикл while продолжает генерировать случайные числа, пока ВСЕ (следовательно, &&) индексы событий не будут идентичны друг другу. Используя || разрушит эту логику. –

ответ

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] } 
    } 
} 

ОК, вот как я бы это сделать, но если мы хотим, чтобы держать его в стиле у вас есть, мы все еще можем сделать это. Вам все равно понадобится allEvents, чтобы быть static.

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] 
    ... 

Но главный урок во всем этом является то, что вы можете 'Свойства доступа в объекте до инициализации объекта.