Swift-修剪并映射数组中的第一个字母

Swift-修剪并映射数组中的第一个字母,swift,dictionary,indexing,flatmap,Swift,Dictionary,Indexing,Flatmap,我有一个超过2500个客户名称的列表,并希望创建一个按字母顺序排列的姓氏索引(姓氏的第一个字母)。 当LastName前面有空格时(我知道,遗留数据问题应该在以后得到修复),它们应该被删除。如果没有可用的姓氏,那么它应该作为indexArrayro中的最后一项出现 结果应该是 indexArray==[“A”、“G”、“I”、“M”、“S”、“Z”和“”的大写字母 这就是我目前得到的 struct MyObject { let firstName: String let last

我有一个超过2500个客户名称的列表,并希望创建一个按字母顺序排列的姓氏索引(姓氏的第一个字母)。 当LastName前面有空格时(我知道,遗留数据问题应该在以后得到修复),它们应该被删除。如果没有可用的姓氏,那么它应该作为indexArrayro中的最后一项出现

结果应该是 indexArray==[“A”、“G”、“I”、“M”、“S”、“Z”和“”的大写字母

这就是我目前得到的

struct MyObject {
    let firstName: String
    let lastName : String
}

let objectArray : [MyObject?] = [
    MyObject(firstName: "piet", lastName: "mozilla"),
    MyObject(firstName: "jol", lastName: " godzilla"),
    MyObject(firstName: "", lastName: "Anubis"),
    MyObject(firstName: "paul", lastName: ""),
    MyObject(firstName: "", lastName: "Strawberry"),
    nil,
    MyObject(firstName: "jol", lastName: "zwordfish"),
    MyObject(firstName: "jol", lastName: ""),
    MyObject(firstName: "", lastName: "Zwordfish"),
    nil,
    MyObject(firstName: "pot", lastName: "IronFly")
]


extension Array {  
    mutating func rearrange(from: Int, to: Int) {
        insert(remove(at: from), at: to)
    }
}

extension String
{   
    func trim() -> String
    {
        return self.trimmingCharacters(in: .whitespaces)
    }
}

let arrayWithNoNils = objectArray.flatMap { $0 } // to remove the 'nil's

let indexedArray = arrayWithNoNils.map({ $0.lastName.prefix(1) }) // get the first character

var indexArr : Array = Set(indexedArray).sorted() as Array // make it unique and sort

if indexArr.count > 0 && indexArr[0] == "" { // move the empty one as last
    let cnt = indexArr.count - 1
    indexArr.rearrange(from: 0, to: cnt)
}
有人帮我修一下吗? 我想我可以在边上用它

arrayWithNoNils.map({ $0.lastName.prefix(1) })
差不多

arrayWithNoNils.map({ $0.lastName.trim.prefix(1) })
有什么建议吗


一如既往地谢谢你。

这就是你要找的吗

let fixedArray = objectArray.map({ (object) -> MyObject? in
    guard let existedObject = object else { return nil }
    return MyObject(firstName: existedObject.firstName, lastName: existedObject.lastName.trimmingCharacters(in: .whitespacesAndNewlines))
})

这就是你要找的吗

let fixedArray = objectArray.map({ (object) -> MyObject? in
    guard let existedObject = object else { return nil }
    return MyObject(firstName: existedObject.firstName, lastName: existedObject.lastName.trimmingCharacters(in: .whitespacesAndNewlines))
})

这将通过使用compactMap删除nil对象并修剪和获取姓氏的第一个字符,为您提供索引数组。然后将其强制转换为一个集合以删除重复项,并最终排序,其中闭包确保“”排序在最后

let indexArray = Set(objectArray
    .compactMap { $0?.lastName.trimmingCharacters(in: .whitespaces).prefix(1).uppercased()})
    .sorted(by: {
        if $0.isEmpty {
            return false
        }
        if $1.isEmpty {
            return true
        }
        return $0 < $1
    })
let indexArray=Set(objectArray)
.compactMap{$0?.lastName.trimmingCharacters(在:。空格中)。前缀(1)。大写()
.分类(按:{
如果0.5美元是空的{
返回错误
}
如果1.5美元是空的{
返回真值
}
返回$0<$1
})

这将通过使用compactMap删除nil对象并修剪和获取姓氏的第一个字符,为您提供索引数组。然后将其强制转换为一个集合以删除重复项,并最终排序,其中闭包确保“”排序在最后

let indexArray = Set(objectArray
    .compactMap { $0?.lastName.trimmingCharacters(in: .whitespaces).prefix(1).uppercased()})
    .sorted(by: {
        if $0.isEmpty {
            return false
        }
        if $1.isEmpty {
            return true
        }
        return $0 < $1
    })
let indexArray=Set(objectArray)
.compactMap{$0?.lastName.trimmingCharacters(在:。空格中)。前缀(1)。大写()
.分类(按:{
如果0.5美元是空的{
返回错误
}
如果1.5美元是空的{
返回真值
}
返回$0<$1
})

您可以尝试以下方法:

let firstLetters = objectArray.map { item -> String in
    guard let item = item else { return "" }
    return String(item.lastName.trim().prefix(1)).uppercased()
}

let indexArray = Array(Dictionary(grouping: firstLetters, by: { $0 }).keys)
    .sorted {
        if $0 == "" { return false }
        if $1 == "" { return true }
        return $0 < $1
    }

print(indexArray) // ["A", "G", "I", "M", "S", "Z", ""]
让firstLetters=objectArray.map{item->String进入
guard let item=item else{return”“}
返回字符串(item.lastName.trim().prefix(1)).uppercased()
}
让indexArray=Array(字典(分组:第一个字母,按:{$0}).keys)
.分类{
如果$0==”{return false}
如果$1==“{return true}”
返回$0<$1
}
打印(索引排列)/[“A”、“G”、“I”、“M”、“S”、“Z”和“”]

您可以尝试以下方法:

let firstLetters = objectArray.map { item -> String in
    guard let item = item else { return "" }
    return String(item.lastName.trim().prefix(1)).uppercased()
}

let indexArray = Array(Dictionary(grouping: firstLetters, by: { $0 }).keys)
    .sorted {
        if $0 == "" { return false }
        if $1 == "" { return true }
        return $0 < $1
    }

print(indexArray) // ["A", "G", "I", "M", "S", "Z", ""]
让firstLetters=objectArray.map{item->String进入
guard let item=item else{return”“}
返回字符串(item.lastName.trim().prefix(1)).uppercased()
}
让indexArray=Array(字典(分组:第一个字母,按:{$0}).keys)
.分类{
如果$0==”{return false}
如果$1==“{return true}”
返回$0<$1
}
打印(索引排列)/[“A”、“G”、“I”、“M”、“S”、“Z”和“”]
我找到了它

这条线应该是

let indexedArray = arrayWithNoNils.map({ (($0.lastName.trim)().uppercased()).prefix(1)
我找到了

这条线应该是

let indexedArray = arrayWithNoNils.map({ (($0.lastName.trim)().uppercased()).prefix(1)

您能否解释一下当前代码的预期结果和实际结果。请为您包含的示例数据添加预期输出。现在还不清楚您想要实现什么。说得好,因为现在我记得我希望结果是大写的。您能解释一下当前代码的预期结果和实际结果是什么吗。请为您包含的示例数据添加预期输出。现在还不清楚您想要实现什么。说得好,因为现在我记得我希望结果是大写的。在快捷界面列表的右侧,有一个索引(按钮),用户可以单击该索引滚动到与该字母对应的姓氏的字母。@LordAnubis Ok,我没有看到您问题底部的代码,我想我会使用您的代码,并从中创建一个扩展。在快捷界面列表的右侧,用户可以单击一个索引(按钮),滚动到与该字母对应的姓氏的字母。@LordAnubis Ok,我没有看到你问题底部的代码,我想我会用你的代码创建一个扩展。