将两个循环合二为一

时间:2016-03-22 22:54:05

标签: arrays swift loops dictionary optimization

此代码用于按首字母对字符串数组进行分组。

//plain array
var list = ["apple", "apricot", "banana", "blackberry"]

//dictionary of arrays
var dict = Dictionary<String, Array<String>>()

//create necessary keys from first characters
for word in list {
    dict[ String( word.characters.prefix(1) ) ] = [ ]
}

//add words to the key of their first character
for word in list {
    dict[ String( word.characters.prefix(1) ) ]?.append( word )
}

//output dictionary
print(dict)

此示例将输出如下字典:

[ "b": ["ba", "bb"],
  "a": ["aa", "ab"] ]

代码有两个类似的for循环。它们可以组合成一个不影响输出的循环吗?

2 个答案:

答案 0 :(得分:3)

听起来像是groupBy功能的完美工作:

extension Array {
    func groupBy<T: Hashable>(f: Element -> T) -> [T: [Element]] {
        var results = [T: [Element]]()
        for element in self {
            let key = f(element)
            if results[key] != nil {
                results[key]!.append(element)
            } else {
                results[key] = [element]
            }
        }
        return results
    }
}

var list = ["apple", "apricot", "banana", "blackberry"]
let dict = list.groupBy {
    String($0.characters.prefix(1))
}

让我们一步一步地走过去:

  • groupBy接受一个函数,该函数为数组中的每个元素提供一个键。它返回一个字典,其中包含键和具有相同键的元素列表。
  • f是给予钥匙的功能。对于数组中的每个元素,检查结果字典是否已具有该键。如果是,它将被附加到该键的元素列表中。如果不是,则为该密钥创建一个新数组。

答案 1 :(得分:1)

    //plain array
    let list = ["apple", "apricot", "banana", "blackberry"]

    //dictionary of arrays
    var dict = Dictionary<String, Array<String>>()

    //create necessary keys from first characters
    for word in list {

        if let _ = dict[ String( word.characters.prefix(1) )] {
            dict[ String( word.characters.prefix(1) )]?.append(word)
        }
        else{
            dict[ String( word.characters.prefix(1) ) ] = [word]
        }
    }

    //output dictionary
    print(dict)