2016-11-12 2 views
1

Я создал структуру и хочу заполнить ее моими данными.Как заполнить данные из NSMutableArray в структуру с помощью Swift3

Моя структура:

struct CrimeNameSection { 

var firstChar: Character 
var name: [String] 
var detail: [String] 
var time: [String] 


init(firstLetter: Character, object1: [String], object2: [String], object3: [String]) { 

    firstChar = firstLetter // First letter of 'name' 
    name = object1 
    detail = object2 
    time = object3 
} 

Первое значение моей структуры («firstChar») должен держать первую букву «имя», чтобы создать алфавитный разделы в Tableview, остальные («имя»,» detail ',' time ') должны содержать данные из моей базы данных (три столбца: имя, деталь, время).

Мой код:

var marrCrimesData : NSMutableArray! // Hold the database 

func getSectionsFromData() -> [CrimeNameSection] { 
    guard marrCrimesData != nil else { 
     return [] 
    } 


    var sectionDictionary = [CrimeNameSection]() 
    for crime in marrCrimesData { 
     let crime = crime as! CrimesInfo 
     let firstChar = CrimeNameSection(firstLetter: crime.name[crime.name.startIndex], object1: [crime.name], object2: [crime.detail], object3: [crime.time]) 
     if var names = firstChar { 
      names.append(crime.name) 
      sectionDictionary[firstChar] = names 
     } else { 
      sectionDictionary[firstChar] = [crime.name] 
     } 
    } 

    let sections = sectionDictionary.map { (key, value) in 
     return CrimeNameSection(firstLetter: key, name: value) 
    } 
    let sortedSections = sections.sorted { $0.firstLetter < $1.firstLetter } 

    return sortedSections 
} 

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

+0

какая у вас ошибка? – Robert

ответ

1

Рассмотрим

struct Crime { 
    let name: String 
    let detail: String 
    let time: String 
} 

let crimes = [ 
    Crime(name: "Foo", detail: "detail 1", time: "9am"), 
    Crime(name: "Bar", detail: "detail 2", time: "10am"), 
    Crime(name: "Baz", detail: "detail 3", time: "11am"), 
    Crime(name: "Qux", detail: "detail 4", time: "12am") 
] 

Одним из подходов являются просто построить словарь, индексированный по первому символу, а затем отсортировать его:

var crimeIndex = [Character: [Crime]]() 
for crime in crimes { 
    if let firstCharacter = crime.name.characters.first { 
     if crimeIndex[firstCharacter] == nil { 
      crimeIndex[firstCharacter] = [crime] 
     } else { 
      crimeIndex[firstCharacter]?.append(crime) 
     } 
    } 
} 

let sortedIndex = crimeIndex.sorted { $0.0 < $1.0 } 

Преимуществом выше является то, что мы можем использовать словарь для эффективно найти раздел. Если вы действительно хотите использовать свою настраиваемую структуру имен, сначала я должен использовать массив из объектов Crime (имеющие разрозненные массивы свойств Crime могут быть хрупкими, например, если позднее вы решите добавить сортировку преступления). Так это может выглядеть следующим образом:

struct CrimeNameSection { 
    let firstCharacter: Character 
    var crimes: [Crime] 
} 

И потому, что мы потеряли часть Dictionary эффективности для нахождения индекса и вручную перебирать ищу секцию, и я буду идти вперед и делать вставку сортировать по время, избавив меня от необходимости делать отдельный вид позже:

var crimeSections = [CrimeNameSection]() 
for crime in crimes { 
    if let firstCharacter = crime.name.characters.first { 
     var hasBeenAdded = false 

     for (index, crimeIndex) in crimeSections.enumerated() { 
      if firstCharacter == crimeIndex.firstCharacter { // if we found section, add to it 
       crimeSections[index].crimes.append(crime) 
       hasBeenAdded = true 
       break 
      } 
      if firstCharacter < crimeIndex.firstCharacter { // if we've passed where the section should have been, insert new section 
       crimeSections.insert(CrimeNameSection(firstCharacter: firstCharacter, crimes: [crime]), at: index) 
       hasBeenAdded = true 
       break 
      } 
     } 

     // if we've gotten to the end and still haven't found section, add new section to end 

     if !hasBeenAdded { 
      crimeSections.append(CrimeNameSection(firstCharacter: firstCharacter, crimes: [crime])) 
     } 
    } 
} 
0

Прежде всего вы не можете создать экземпляр массива и сопоставления над ним, как словарь

var sectionDictionary = [CrimeNameSection]() // Here you are init an Array 

Для словаря вы должны также указать ключ, например, если ключ является строкой :

var sectionDictionary = [String: CrimeNameSection]() // Dictionary init 

Но имейте в виду, что ключ должен быть уникальным, чтобы диктофон работал надлежащим образом.
Другой проблемой здесь является конструктор в функции .map, потому что вы не создали конструктор для вашего CrimeNameSection, что только принимает два параметра:

init(firstLetter: Character, object1: [String], object2: [String], object3: [String]) { 

    firstChar = firstLetter // First letter of 'name' 
    name = object1 
    detail = object2 
    time = object3 
} 

// Another constructor with 2 arguments 
init(firstLetter: Character, object1: [String]) { 

    firstChar = firstLetter // First letter of 'name' 
    name = object1 
    detail = []() 
    time = []() 
} 

Если вы не хотите использовать другой конструктор, то вы должны укажите значения по умолчанию для object2 и object3 в вашем исходном конструкторе.

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