简体   繁体   English

如何使用Swift3将NSMutableArray中的数据填充到结构中

[英]How to populate data from NSMutableArray into struct using Swift3

I'v created a struct and I want to populate it with my data. 我已经创建了一个结构,我想用我的数据填充它。

My struct: 我的结构:

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
}

The first value of my struct ('firstChar') should hold the first letter in 'name' to create an alphabetic sections in tableView, the rest ('name','detail','time') should hold the data from my database (three columns: name, detail, time). 我的结构的第一个值('firstChar')应该保存'name'中的第一个字母以在tableView中创建字母部分,其余的内容('name','detail','time')应该保存我数据库中的数据(三列:名称,详细信息,时间)。

My code: 我的代码:

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 
}

I get errors all over the place, I need help with storing the data inside my struct and sort it alphabetically. 我到处都是错误,我需要帮助将数据存储在结构中并按字母顺序排序。 Thank you all 谢谢你们

First of all you could not instantiate an Array and map over it like a dictionary 首先,您无法实例化数组并像字典一样映射它

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

For a dictionary you have also to specify the key, for instance if the key is a string: 对于字典,还必须指定键,例如,如果键是字符串:

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

But be aware that the key have to be unique so that the dict would work properly. 但是请注意,密钥必须唯一,以便字典可以正常工作。
Another problem here is the constructor in your .map function because you have not created a constructor for your CrimeNameSection that only takes two parameters: 这里的另一个问题是您的.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 = []()
}

If you don't want to use another constructor then you have to provide default values to object2 and object3 in your initial constructor. 如果您不想使用其他构造函数,则必须在初始构造函数中为object2和object3提供默认值。

Consider 考虑

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")
]

One approach is to just build an dictionary indexed by the first character and then sort it: 一种方法是只构建一个按第一个字符索引的字典,然后对其进行排序:

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 }

The advantage of the above is that we can use the dictionary to efficiently find the section. 上面的优点是我们可以使用字典来有效地找到该部分。 If you really want to use your custom "name section" structure, I'd first make it to use an array of Crime objects (having disjointed arrays of the properties of a Crime can be fragile, eg if you later decide to add sorting of the crimes). 如果你真的想用您的自定义“名节”结构,我想先让它使用数组Crime对象(具有的属性脱节阵列Crime可以是脆弱的,例如,如果你决定添加的分类罪行)。 So it might look like: 因此可能看起来像:

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

And because we've lost some of the Dictionary efficiency for finding the index and have manually iterate through looking for the section, and I'll go ahead and do an insertion sort at the time, saving me from having to do a separate sort later: 而且,由于我们失去了查找索引的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]))
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM