2015-07-31 3 views
3

Я не эксперт в Swift, и я использовал его в течение нескольких месяцев для создания приложений Mac. Я хотел бы представить в памяти структуру данных, подобную структуре PHP ассоциативных массивов, но в Swift. Давайте представим себе, что у меня есть таблица данных для загрузки в память со следующими полями/записей:Swift: ассоциативный массив с несколькими ключами: значения

ID Surname Name 
1 XXX  YYY 
2 ZZZ  WWW 
3 JJJ  KKK 

То, что я хотел бы получить это ассоциативный массив, как тот, который я смог бы получить в PHP:

$arr[1]["Surname"] = "XXX" 
$arr[1]["Name"] = "YYY" 
$arr[2]["Surname"] = "ZZZ" 
$arr[2]["Name"] = "WWW" 

Я просто не могу найти нужную структуру данных в Свифт, чтобы получить тот же результат. Я пробовал использовать следующий фрагмент кода:

class resObject: NSObject { 
    private var cvs = [Int: [String: String]]() 

    override init() { 

     self.cvs[0] = ["Name" : "XXX"] 
     self.cvs[0] = ["Surname" : "YYY"] 
     self.cvs[1] = ["Name" : "ZZZ"] 
     self.cvs[1] = ["Surname" : "WWW"] 

     for (key, arr) in cvs { 
      let sur = arr["Surname"] 
      let nam = arr["Name"] 

      println("Row \(key) - Surname: \(sur), Name: \(nam)") 
     } 

     super.init() 
    } 
} 

Он выглядит очень близко, но он не работает. Что я получаю на выходе следующий (я не забочусь о «факультативных (ов)»:

Row 0 - Surname: Optional("XXX"), Name: nil 
Row 1 - Surname: Optional("ZZZ"), Name: nil 

Я попытался сделать некоторые тесты в отладке, и я заметил, что данные, которые сохраняются в памяти это то же самое, что и у последнего ключа: используется пара значений (т. е. если я сначала назначу фамилию и имя второй, я получаю фамилию как nil и Name с правильным значением).

Пожалуйста, учтите, что, как в примере, t знать структуру данных, когда я объявляю переменную, поэтому объявляю ее пустой и заполняю ее программно позже.

Я не знаю, если я просто не объявляю структуру данных c правильно, или если это Swift, что не позволяет этого делать. Любая помощь будет оценена.

Большое спасибо. С уважением, Alessio

+0

Похоже, что вы хотите, это объект объектов словаря. – picciano

+0

Не согласен. Вы действительно думаете, что он хочет, чтобы каждый элемент массива был аморфным и расширяемым, чтобы содержать произвольные сопоставления строк String -> String? Это не структурированные данные, требующие жестко заданных свойств? – BaseZen

ответ

7

Один из способов - Dictionary из structs. Рассмотрим:

struct Person { 
    var firstName: String 
    var lastName: String 
} 

var peopleByID = [ Int: Person ]() 
peopleByID[1] = Person(firstName: "First", lastName: "Last") 
peopleByID[27] = Person(firstName: "Another", lastName: "LastName") 

var myID = 1 // Try changing this to 2 later 
if let p = peopleByID[myID] { 
    println("Found: \(p.firstName) with ID: \(myID)") 
} 
else { 
    println("No one found with ID: \(myID)") 
} 

Вы можете обновить структуру:

peopleByID[1].firstName = "XXX" 
peopleByID[27].lastName = "ZZZ" 

Вы можете перебирать свободно:

for p in peopleByID.keys { 
    println("Key: \(p) value: \(peopleByID[p]!.firstName)") 
} 

Обратите внимание, что простой массив [Человек] не так жарко, потому что идентификаторы:

- не могут быть Интс, но часто являются строками

- даже если они остаются Ints, массив занимает хранилище пропорционально индексу с наивысшим номером, тогда как словарь занимает только хранилище пропорционально количеству сохраненных объектов. Представьте себе, хранить только два идентификаторы: 523123 и 2467411.

EDIT

Это кажется, что вы не знать атрибуты загодя, которые будут идти в каждый Person объект.Это странно, но вы должны это сделать:

struct Person { 
    var attributes = [String : String]() // A dictionary of String keys and String values 
} 
var peopleByID = [ Int : Person ]() 

// and then: 

var p1 = Person() 
var p2 = Person() 
p1.attributes["Surname"] = "Somename" 
p1.attributes["Name"] = "Firstname" 
p2.attributes["Address"] = "123 Main St." 
peopleByID[1] = p1 
peopleByID[2] = p2 

if let person1 = peopleByID[1] { 
    println(person1.attributes["Surname"]!) 

    for attrKey in person1.attributes.keys { 
     println("Key: \(attrKey) value: \(person1.attributes[attrKey]!)") 
    } 
} 
+0

Большое спасибо, это то, что я искал (на самом деле лучше, так как я не знал, что массивы тратят столько места памяти в таких ситуациях, как мои). Просто, чтобы уточнить (возможно, это не было в исходном сообщении), я знаю атрибуты с самого начала, поэтому первое решение является идеальным, также с точки зрения понятности кода. – Alessio

 Смежные вопросы

  • Нет связанных вопросов^_^