简体   繁体   English

Swift 2 - 使用从A到Z的键将数组分离到字典中

[英]Swift 2 - Separating an array into a dictionary with keys from A to Z

I have an array, for instance ["Apple", "Banana", "Blueberry", "Eggplant"] and I would like to convert it to a dictionary like follows: 我有一个数组,例如["Apple", "Banana", "Blueberry", "Eggplant"] ,我想将其转换为如下字典:

[
    "A" : ["Apple"],
    "B" : ["Banana", "Blueberry"],
    "C" : [],
    "D" : [],
    "E" : ["Eggplant"]
]

I am using Swift 2 on Xcode 7 beta 4. Thanks! 我在Xcode 7 beta 4上使用Swift 2.谢谢!

Using only Swift 2 objects and methods, and with a key for each letter in the alphabet: 仅使用Swift 2对象和方法,并使用字母表中每个字母的键:

let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".characters.map({ String($0) })

let words = ["Apple", "Banana", "Blueberry", "Eggplant"]

var result = [String:[String]]()

for letter in alphabet {
    result[letter] = []
    let matches = words.filter({ $0.hasPrefix(letter) })
    if !matches.isEmpty {
        for word in matches {
            result[letter]?.append(word)
        }
    }
}

print(result)

I composed this in Xcode playground: 我在Xcode playground中编写了这个:

import Foundation

var myArray = ["Apple", "Banana", "Blueberry", "Eggplant"]

var myDictionary : NSMutableDictionary = NSMutableDictionary()

for eachString in myArray as [NSString] {

    let firstCharacter = eachString.substringToIndex(1)

    var arrayForCharacter = myDictionary.objectForKey(firstCharacter) as? NSMutableArray

    if arrayForCharacter == nil
    {
        arrayForCharacter = NSMutableArray()
        myDictionary.setObject(arrayForCharacter!, forKey: firstCharacter)
    }

    arrayForCharacter!.addObject(eachString)
}

for eachCharacter in myDictionary.allKeys
{
    var arrayForCharacter = myDictionary.objectForKey(eachCharacter) as! NSArray

    print("for character \(eachCharacter) the array is \(arrayForCharacter)")
}

I found this question helped me better understand some concepts which I had been thinking about. 我发现这个问题帮助我更好地理解了我一直在思考的一些概念。 Here is an alternative take based on the accepted correct answer which is slightly more concise and where the alphabet is generated programmatically. 这是基于可接受的正确答案的替代方案,该答案稍微简洁并且以编程方式生成字母表。 This is Swift 2 in Xcode 7. 这是Xcode 7中的Swift 2。

let words = ["Apple", "Banana", "Blueberry", "Eggplant"]
let alphabet = (0..<26).map {n in String(UnicodeScalar("A".unicodeScalars["A".unicodeScalars.startIndex].value + n))}
var results = [String:[String]]()
for letter in alphabet {
    results[letter] = words.filter({$0.hasPrefix(letter)})
}

print(results)

I believe but am not certain that the let alphabet line could be made more concise. 我相信但不确定let alphabet线可以更简洁。

Here's my solution. 这是我的解决方案。 Works in pure Swift 2 and in O(n) time where n is the length of the list of words (and assuming a dictionary is implemented as a hash table). 适用于纯Swift 2和O(n)时间,其中n是单词列表的长度(假设字典是作为哈希表实现的)。

var dictionary: [String : [String]] = [ "A" : [], "B" : [], "C" : [], "D" : [],
"E" : [], "F" : [] /* etc */ ]

let words = ["Apple", "Banana", "Blueberry", "Eggplant"]

for word in words
{
    let firstLetter = String(word[word.startIndex]).uppercaseString

    if let list = dictionary[firstLetter]
    {
        dictionary[firstLetter] = list + [word]
    }
    else
    {
         print("I'm sorry I can't do that Dave, with \(word)")
    }
}

print("\(dictionary)")

I have just made such useful Array Extension that enables to map Array of Objects to Dictionary of Character Indexed Objects based on selected property of object. 我刚刚制作了这样有用的数组扩展,它可以根据对象的选定属性将对象数组映射到字符索引对象字典。

    extension Array {

    func toIndexedDictionary(by selector: (Element) -> String) -> [Character : [Element]] {

        var dictionary: [Character : [Element]] = [:]

        for element in self {
            let selector = selector(element)
            guard let firstCharacter = selector.firstCharacter else { continue }

            if let list = dictionary[firstCharacter] {
                dictionary[firstCharacter] = list + [element]
            } else {
                // create list for new character
                dictionary[firstCharacter] = [element]
            }
        }
        return dictionary
    }
}

extension String {
    var firstCharacter : Character? {
        if count > 0 {
            return self[startIndex]
        }
        return nil
    }
}

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

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